Backbone.js の初心者です。 一般的な質問: UI に表示するためにコレクション内のモデルの数を追跡するベスト プラクティスは何ですか? 私のユースケースにはサーバー側の変更が含まれる可能性があるため、コレクションが同期されるたびに、UI をストレージから正しい番号に更新できるようにする必要があります。
私は、amdjsプロジェクトの Backbone.js v1.0.0 と Underscore v1.4.4 と Require.js v2.1.6 を使用しています。
具体例:ユーザーがアイテムを追加/削除している間、継続的に更新される「カート内のアイテム数」を表示する単純なショッピング カート。この例では、私はほとんどそこにいますが、(1) 私のコードは常にモデルの実際の数よりも 1 つ少なく、(2) これを行うにはもっと良い方法があると感じています!
これが私の初心者コードです。まず、ユーザーがボタンでカートに追加できるアイテムのコレクションを用意します。(注: 簡潔にするために、コード例では AMD の定義と戻り値はすべて削除されています。)
var PackagesView = Backbone.View.extend({
el: $("#page"),
events: {
"click .addToCart": "addToCart"
},
initialize: function(id) {
this.collection = new PackagesCollection([],{id: id.id});
this.collection.fetch({
reset: true
});
this.collection.on("reset", this.render, this);
},
render: function(){
//other rendering stuff here
..............
//loop through models in collection and render each one
_.each(this.collection.models, function(item){
that.renderPackages(item);
});
}
renderPackages: function(item){
var packageView = new PackageView({
model: item
});
this.$el.append(packageView.render().el);
},
次に、上記のPackagesViewコードによって呼び出されるカートPackageView内の個々のアイテムのビューを用意します。「クリック」イベントが関連付けられているパッケージごとに「カートに追加」ボタンがあります。
var PackageView = Backbone.View.extend({
tagName:"div",
template:$(packageTemplate).html(),
events: {
"click .addToCart": "addToCart"
},
render:function () {
var tmpl = _.template(this.template);
this.$el.html(tmpl(this.model.toJSON()));
return this;
},
addToCart:function(){
cartView = new CartView();
cartView.collection.create(new CartItemModel(this.model));
}
最後に、カート内のすべてのアイテムのコレクションを持つCartViewがあります。コレクションへの変更に対応する listenTo メソッドを追加しようとしましたが、サーバーとの同期も維持されませんでした。
var CartView = Backbone.View.extend({
el: $("#page"),
initialize:function(){
this.collection = new CartCollection();
this.collection.fetch({
reset: true
});
this.listenTo(this.collection, 'add', this.updateCartBanner);
this.collection.on("reset", this.render, this);
},
render: function(){
$('#cartCount').html(this.collection.length);
},
updateCartBanner: function(){
//things did not work here. Just putting this here to show something I tried.
}
特定の例の最終結果: .create が正しく動作し、PUT 要求が送信され、サーバーがデータをデータベースに追加し、「リセット」イベントが呼び出されます。ただし、CartViewの render() 関数は、コレクション内の正しいモデル数を表示しません。「カートに追加」ボタンを初めてクリックしたときに、$('#cartCount') 要素が入力されません。その後はいつでもデータが取り込まれますが、サーバー上の実際のカウントからマイナス 1 です。これは、.create と .fetch があり、.create が終了する前に .fetch が発生しているため、常にサーバーの 1 秒遅れているためだと思います。
最終結果、私はこれを正しい方法で構造化していません。正しい方向へのヒントは役に立ちます!