1

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 秒遅れているためだと思います。

最終結果、私はこれを正しい方法で構造化していません。正しい方向へのヒントは役に立ちます!

4

2 に答える 2