2011-12-11 11 views
9

私のコレクションがキャッシュに残っていることを確認して、一度だけ取得されるようにするにはどうすればよいでしょうか?backbone.jsのコレクションをキャッシュしますか?

キャッシュ層を実装する必要がありますか?変数が必要な場所にあれば、Collection変数を共有する必要がありますか? jQuerys AJAXの設定を信頼できますか? ($.ajaxSetup ({ cache: true });

それが今に見えるよう、基本的なコレクション:

theCollection = Backbone.Collection.extend({ 
    model: theModel, 
    url: "source.json" 
}); 

if (typeof myCollection === 'undefined') { 
    var myCollection = new theCollection; // Only allow it to be created once 
} 
+0

バウンティはONです!この件についてもう少し意見をいただきたい! – Industrial

+0

localStorageを使用してコレクションをブラウザにキャッシュしたままにするか、コレクションがシングルトンであることを確認してください。常にフェッチされた同じインスタンスを呼び出す必要がありますか? –

答えて

16

私はあなたのケースでコレクションマネージャーの並べ替えを実装します:

var manager = (function(){ 

    var constructors = { 
    'example': ExampleCollection 
    }; 
    var collections = {}; 

    return { 
    getCollection: function(name) { 
     if(!collections[name]) { 
     var collection = new constructors[name](); 
     collection.fetch(); 
     collections[name] = collection; 
     } 
     return collections[name]; 
    } 
    } 
})(); 

をここで管理者がコレクションをインスタンス化し、それらを取得する責任があります。電話をしたとき:

var exampleCollection = manager.getCollection('example'); 

データがすでに取得されているサンプル収集のインスタンスが表示されます。このコレクションが再度必要なときはいつでも、メソッドを再度呼び出すことができます。その後、再度フェッチする必要はなく、まったく同じインスタンスを取得します。

これは非常に単純な管理者の例であり、実装して拡張することができる多くの追加機能があります。

私はこの問題をより低いレベル(例えば、$ .ajaxのトランスポート層)で処理しないことを強くお勧めします。これを行うと、コレクションが複数回取得されるのを防ぐことができますが、アプリケーションの周りに同じIDを持つ異なるモデルインスタンスが存在することになります。すべてのコレクションインスタンスは独自のモデルを作成します。

私が現在取り組んでいるCouchAppでは、異なるコレクションのモデルインスタンスが重複しないようにする必要があることも発見しました(異なるDBビューは同じモデルデータを返すことができます)。これはマネージャに別のコレクションを持ち、既にアプリケーションにロードされているすべてのモデルを追跡することで解決されています。

最後に、コレクションまたはサーバーからのコレクションの更新を処理するマネージャーにリフレッシュメソッドを実装することを検討してください。 fetchメソッドでこれを行うと、コレクション全体がリセットされ、すべてのモデルが破棄されてから再作成されます。これは、このコレクションのモデルが(通常はそうであるように)アプリ内の別の場所で参照されていると悪いことです。それらのインスタンスは、あなたのアプリで時代遅れになり、複製されます。リフレッシュメソッドは、着信IDを持つインスタンスがすでにキューイングコレクションに存在するかどうかをチェックします。そうであれば更新され、そうでなければ追加されます。

0

あなたはのlocalStorageにあなたのコレクションを保存しようとすることができます。ここにリンク(http://documentcloud.github.com/backbone/#examples-todos)があります。

アプリはLocalStorageアダプタを使用して、サーバーに送信するのではなく、ブラウザ内のすべてのToDoを透過的に保存します。

私はそれが役に立てば幸い:)

2

キャッシングによって実際にシングルトンを意味するので、モジュラーJSアプリケーションの複数の場所から同じドメインリストを参照できるようにするには、RequireJSを使用します。コレクションをアプリケーション内のモジュールに分けることができます。アプリケーションのモジュールは、使用する場所に関係なく必要となります。擬似コードで:

require(["myCollection"], 
    function(myCollection) { 
     var MyView = Backbone.View.extend(); 
     new MyView({ 
      collection: myCollection 
     }).render(); 
    } 
); 

あなたのコールバック関数は常に、あなたのmyCollectionモジュールを定義するときに返された同じインスタンスを取得します。すべてのビューからそのインスタンスにバインドし、リフレッシュされるたびに、それらのビューはイベントトリガーを取得し、自身を更新できます。

+0

これはリフレッシュを引き起こしませんか?あなたのコレクションモジュールが 'Backbone.Collection.extend({model:myCollection、url:app.baseUrl()+ 'myCollection'})を返すように定義されているとします。 – seebiscuit

+0

どこにあるかによって、_.fetch()_が呼び出されます。実際、この場合は、実際にコレクションモジュールファクトリ関数からインスタンスを返す必要があり、そのインスタンスは異なるビュー間で共有されます。 –

0

単純な解決策は、すべてのjavascriptコードで同じ変数を使用するように、コレクションのグローバル変数を作成することです。

ページのロード時

$(function() { 
    myCollection = theCollection(); 
    myCollection.fetch(); 
}); 

だけVARが宣言myCollectionに使用されていないので、それはグローバル変数になりコレクションを取得します。

もちろん、これは簡単な実装です。より堅牢な実装がありますが、必要に応じて、過度の作業になるかもしれません。

0

私はProTomのソリューションに似た何かをやりました。名前に基づいてコレクションを動的に初期化するのではなく、関数を使ってコレクションを設定することにしました。私のアプリケーションを通じて、どこから来たのかによってコレクションを別々に初期化する必要がありました。これは私のニーズにとって最善の方法であることが判明しました。ここではCoffeeScriptのです:

キャッシュ:

cachedCollections: {} 
getCollection: (key, block) -> 
    collection = @cachedCollections[key] 
    return collection if collection 
    collection = block() 
    @cachedCollections[key] = collection 
    collection 

使用法:

commentCollection = getCollection "comments-#{postId}", -> 
    collection = new CommentCollection 
    collection.url = "/api/posts/#{postId}/comments" 
    collection 
関連する問題