1

Backbone.js 新手在这里。 一般问题:跟踪集合中的模型数量以便在 UI 上显示它的最佳实践是什么?我的用例可能涉及服务器端的更改,因此每次同步集合时,我都需要能够将 UI 更新为存储中的正确数字。

我正在使用amdjs项目中的 Backbone.js v1.0.0 和 Underscore v1.4.4 以及 Require.js v2.1.6。

具体示例:显示“购物车中的商品数量”的简单购物车在用户添加/删除商品时不断更新。在这个例子中,我快到了,但是(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);
},

接下来,我查看了购物车PackageView中每个单独项目的视图,该视图由上面的PackagesView代码调用。对于每个具有“点击”事件的包,我都有一个“添加到购物车”按钮。

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 请求,服务器将数据添加到数据库,调用“reset”事件。但是,CartView中的 render() 函数没有显示集合中正确的模型数。第一次单击“添加到购物车”按钮时,$('#cartCount') 元素不会被填充。然后在此之后的任何时候它都会被填充,但我从服务器上的实际计数中减去 1。我相信这是因为我有一个 .create 和一个 .fetch 并且 .fetch 在 .create 完成之前发生,所以我总是在服务器后面 1 。

最终结果,我没有以正确的方式构建它。任何正确方向的提示都会有所帮助!

4

2 回答 2

0

你可以这样尝试:

collection.on("add remove reset sync", renderCallback)

其中 renderCallback 是刷新 UI 的函数。

于 2013-06-18T08:13:41.030 回答
0

找到了我的问题的答案,但绝对可能是一个更好的方法。

如果我更改我的代码,而不是像上面那样为集合中的每个模型创建一个单独的视图,我有一个迭代所有模型并绘制的视图,那么它将起作用。我仍然需要调用 .create ,然后调用 .fetch ,但最终结果是正确的。请注意,在这段代码中,我完全取消了以前的 PackageView,现在一切都由 PackagesView 绘制。

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(){

  var that = this;

  var tmpl = _.template($(packageTemplate).html());

  //loop through models in collection and render each one
  _.each(this.collection.models, function(item){
    $(that.el).append(tmpl(item.toJSON()));
  });

},

addToCart:function(e){

  var id= $(e.currentTarget).data("id");
  var item = this.collection.get(id);

  var cartCollection = new CartCollection();

  var cartItem = new CartItemModel();

  cartCollection.create(new CartItemModel(item), {
    wait: true,
    success: function() {
      console.log("in success create");
      console.log(cartCollection.length);
    },
    error:function() {
      console.log("in error create");
      console.log(cartCollection.length);   
    }

  });

  cartCollection.fetch({
    wait: true,
    success: function() {
      console.log("in success fetch");
      console.log(cartCollection.length);
      $('#cartCount').html(cartCollection.length);
    },
    error:function() {
      console.log("in error fetch");
      console.log(cartCollection.length);   
    }

  });  

结果: .fetch$('#cartCount')回调中的注入模型的更正数。出乎意料的是,除了正确的 .html() 值之外,Chrome 的 console.log 返回值是(服务器端在数据库中开始时有零个模型):

in error create PackagesView.js:88
0 PackagesView.js:89
in success fetch PackagesView.js:97
1 

我从创建中得到了 200 响应,所以这两个回调都应该是“成功”的。我会认为 create 和 fetch 的 Backbone 回调语法是相同的。哦,好吧,它似乎工作。

对此方法的任何反馈表示赞赏!可能是更好的方法来做到这一点。

顺便说一句,这违背了这里的一般建议,尽管我确实有一个“非常简单的列表”,所以从长远来看它可能还可以。

于 2013-06-19T07:05:53.943 回答