純粋なJS上の小さな30行のガジェットコンテナー

habrahabrの30行24行19行、さらには1行でプログラムのクールな実装を見ので、私 habrhabrのきれいなページをそのようなものでフェードアウトすることも決めました。 さらに、 私は長い間招待を望んでいましたが、自分のために新しい質で働く機会がありました。



事実、私は職場でchromeの拡張機能を書くことを学ばなければならなかったということです。 タスク自体は小さいので、最初の考えは額に麺コードを書くことでした。 しかし、localStorageでのデータの受信と保存に苦しみ、これは機能しないと判断しました。少なくとも、localStorageにスレッドラッパーを書き込む必要があります。



一般的に、最初の段階で、拡張機能のさまざまなフレームワークの存在を正直にグーグルで検索しました。 たとえば、 Kangoが見つかりました。 ただし、ブラウザ間の互換性は必要ありません(拡張機能はChrome専用に作成されています)。また、小規模なアプリケーションでサードパーティのライブラリを勉強する必要はないため、独自の自転車を作成することにしました。



コンテナの前に設定されたタスク:



原則として、すべてが小さなコンテナに実装されており、小さなアプリケーションには100%適しています。



したがって、appオブジェクトがあり、addStorage、addValidator、addModuleの3つのメソッドのみが含まれています。



addStorage


拡張機能はユーザー設定をどこかに保存する必要があります。 OK



app.addStorage('option');
      
      





その後、新しいapp.option()メソッドがあります。 このメソッドは、オプショングループのlocalStorageからパラメーターを保存および取得するために使用されます(ウィッシュリスト#2:フライとカツレツを分離します。このグループはユーザー設定専用です。他のパラメーターには別の方法を使用します)。 app.option()は、パラメーターの名前とその値の2つの引数を取ります。 2番目の引数はオプションです。 指定されていない場合、メソッドはパラメーターの値を返し、指定されている場合、この値でパラメーターを保存します。 内部のapp.optionはJSON.stringifyを使用してシリアル化し、JSON.parseを使用してデータを取得します。



 app.option('foo', 'bar'); // localStorage['option.foo'] = 'bar' var a = app.option('foo'); // a = 'bar' //      app.option('foo', [1,2,3]); var a = app.option('foo'); // a = [1,2,3] app.option('foo', { bar: [1,2,3] }); var a = app.option('foo'); // a = { bar: [1,2,3] }
      
      





当然、addStorageはユーザー設定に限定されず、localStorageに配置する必要があるデータを保存できます。



 app.addStorage('whatever_you_want'); app.whatever_you_want('foo', 'bar');
      
      







addValidator


このメソッドは、特定のパラメーターの検証ルールを追加します。 3つの引数を取ります:パラメーターグループの名前、パラメーターの名前、および検証関数自体。 この関数は引数としてこのパラメータの値を取り、目的の値を返す必要があります。 app.option( 'foo')を呼び出すたびに、fooのバリデーターが呼び出されます(指定されている場合)。 例:



 var a = localStorage['option.foo']; // a = undefined var a = app.option('foo'); // a = undefined app.addValidator('option', 'foo', function(foo) { return typeof foo === 'undefined' ? 'bar' : foo; }); var a = localStorage['option.foo']; // a = undefined var a = app.option('foo'); // a = 'bar'
      
      





これは、データがまだないため、最初の拡張機能で非常に便利です。



addModule


addModuleは最も興味深いです。 モジュール全体をコンテナに追加できます。 名前と、メソッドまたはプロパティを含むオブジェクトの2つの引数を取ります。



 app.addModule('foo', { bar: function() { // do something... } }); //     bar app.foo.bar();
      
      





当然、すべてが非常に単純な場合、これには意味がありません。 魔法を追加します。 まず、モジュールオブジェクトにinit()メソッドを含めることができます。 次に、このメソッドは、モジュール(コンストラクターなど)を追加するときに呼び出されます。 その中で、モジュールの初期化ロジックを規定しています。 次に、fooモジュール自体がアプリコンテナーのミニコピーになります。 つまり 関数addStorage、addValidator、さらにaddModuleも使用可能になります! このアプローチがどのように機能するかをより良く示すために、アプリケーションをローカライズするモジュールを実装してみましょう。



 //         trans() -   app.addModule('i18n', { //      data: {}, //   init: function() { // -    ,    option   i18n, (!)      ,     this.addStorage('option'); //   , ..       this.addValidator('option', 'locale', function(locale) { return typeof locale === 'undefined' ? 'ru' : locale; }); document.write('<script src="/path/to/i18n/' + this.option('locale') + '.js"><\/script>'); this.data = data_from_file; $(document).ready(function() { $('.i18n').each(function() { $(this).text(this.trans($(this).attr('data-i18n'))); }); }); }, trans: function(field) { return typeof this.data[field] === 'undefined' ? field : this.data[field]; } });
      
      





this.addStorage('option');



についてもう少し 。 ここでは、i18nモジュールのユーザー設定用のパラメーターのグループを作成しました。 前に使用したものとは一致しません。i18nオブジェクトのコンテキストで作成されます。 アプリケーションでは、このグループへのアクセスはapp.i18n.option('foo');



介してapp.i18n.option('foo');



。 これはすべて、ウィッシュリスト#2に対しても行われます。ユーザー設定をモジュールごとに分割します。 それで、何が何であるかを理解する方が良いです。



したがって、結果として得られたのは、コードの明確で明確な構造であり、グローバルスコープには何もハングアップしていません。 アプリケーションロジックを異なるコンポーネントに分割する機能。 localStorageを使用したトラブルのない作業-彼らが置いたのは得たものです。 データ検証-一度書いて忘れてしまった; コンテナの小さなソースコードはわずか30行です:)



免責事項


私はこのコンテナの100%の必要性と関連性を装います。 建設的なロジックは大歓迎です。 この投稿で誰かが興味深い情報を見つけてくれることを願っています。



コンテナコードの全文


 var app = { validator: {}, addStorage: function(name) { this[name] = function(key, value) { var local_storage_name = typeof this.name === 'undefined' ? name : this.name + '.' + name; if (typeof value === 'undefined') { var param = typeof localStorage[local_storage_name + '.' + key] !== 'undefined' ? JSON.parse(localStorage[local_storage_name + '.' + key]) : null; if (typeof this.validator[name + '.' + key] !== 'undefined') { param = this.validator[name + '.' + key](param); } return param; } localStorage[local_storage_name + '.' + key] = JSON.stringify(value); }; }, addValidator: function(storage, name, callback) { this.validator[storage + '.' + name] = callback; }, addModule: function(name, object) { object.name = name; object.validator = {}; object.addStorage = this.addStorage; object.addValidator = this.addValidator; object.addModule = this.addModule; this[name] = object; if (typeof this[name].init !== 'undefined') { this[name].init(); } } };
      
      






All Articles