2017-03-01 4 views
0

1つのコレクションを使用して複数のビューを生成し、5秒ごとに1つのフェッチを生成しようとしています。Backbone.js複数のビュー、1つのコレクション、1つのフェッチ

以下は実際の例ですが、フェッチすると両方のビューが更新されます。 レスポンスを複数のURLにスプライスすることはできますが、リクエストの数を最小限に抑える必要があります。

私の現在の問題は、コレクションが再フェッチされたときに5秒ごとにすべてのビューを再レンダリングする必要はなく、変更された関連ビューのみです。 コレクション内に複数のモデルを作成し、パーズ関数に正しいオブジェクトを追加してみました。

応答:

{ 
    "json-1": { 
    "sub_1": "3", 
    "sub_2": [], 
    }, 
    "json-2": { 
    "sub_1": [], 
    "sub_2": "1", 
    }, 
} 

//クライアント

を明確にする

const APICollection = Backbone.Collection.extend({ 
    initialize: (models, options) => { 
     this.id = options.id; 
    }, 
    url:() => { 
     return 'https://url.url/' + this.id; 
    }, 
    model: APIModel, 
     parse: (resp) => { 
     return resp; 
    }, 
}); 

const ViewOne = Backbone.View.extend({ 
    initialize: function() { 
     this.collection.bind('sync', this.render, this); 
     this.update(); 
     _.bindAll(this, 'update'); 
    }, 
    render: function (n, collection) { 
     // Render view 
    }, 
    update: function() { 
     let self = this; 
     this.collection.fetch({ 
      update: true, remove: false, success: function() { 
       setTimeout(self.update, 5000); 
      } 
     }); 
    } 
}); 

// Also updates when re-fetched 
const ViewTwo = Backbone.View.extend({ 
    initialize: function() { 
     this.collection.bind('sync', this.render, this); 
    }, 
    render: function (n, collection) { 
     // Render function 
    } 
}); 

let col = APICollection([], {id: 'someid'}); 
new ViewOne({collection: col, el: $("#one")}); 
new ViewTwo({collection: col, el: $("#two")}); 

**更新: "に変更のみ関連するビュー"。これにより、 'ViewOne'は 'json-1'が変更されたときにのみ再レンダリングされ、 'ViewTwo'は再レンダリングされません。現在、両方のビューに完全な応答が送信されます。

+0

"変更された関連ビューのみ。" - あなたはこれを明確にしなければならないでしょう、コレクションの特定のモデルは特定のビューに関連していますか? 1つのビューを別のビューと異なるコレクションにする方法 – mikeapr4

+0

私は質問 – coop

+0

を更新します。あなたの応答が配列を返さない場合、あなたは 'Backbone.Collection'ではなく' Backbone.Model'を使っているはずです。そうすれば、各ビューで 'change:attr'イベントを聞くことができます。 – mikeapr4

答えて

0

オブジェクトの配列ではなくオブジェクトを返すAPIを扱う場合、最良の方法はBackbone.Modelを直接使用することです。

update: function() { 
    let self = this; 
    this.model.fetch({ 
     update: true, remove: false, success: function() { 
      setTimeout(self.update, 5000); 
     } 
    }); 
} 

モデルはまだコレクションと同じようにフェッチされますが、ビューの代わりに、モデルの特定の属性を聴くことができます。

this.collection.bind('sync', this.render, this); 

使用することができ、次の

this.model.bind('change:json-1', this.render, this); 

ヒント:むしろバインドよりlistenToより良い、それはより安全である(docsを参照してください)

this.listenTo(this.model, 'change:json-1', this.render); 
+1

'setTimeout(self.update、5000);'タイムアウトコールバックが初めて実行されたときにコンテキストが失われるため、動作しません。代わりに、 'fetch'関数の' context'オプションを使い、 'this.update.bind(this)'を 'setTimeout'に渡すべきです。 –

+1

また、この手法では、最初のエラーで5秒のループが停止します。 –

+0

@EmileBergeron - コンテキストが失われるのかどうかは確かではありませんが、確かにエラー処理がうまくいくでしょう。私のコードであれば、モデル/ビューの抽象化の観点から見ると、モデル内に再フェッチ機構を追加したいと思いますが、少し洗練されています。 – mikeapr4

関連する問題