Backbone.js集合视图呈现重复项

时间:2012-03-07 13:03:19

标签: javascript backbone.js

在我的Backbone.js应用程序中,我需要能够在集合中的现有项之间插入新项。我到目前为止在网上找到的例子似乎都假设新项目应该附加到集合的末尾。这对我的目的不起作用,所以我选择在添加新项目时重新渲染整个集合。

但是,原始项目不会从视图中删除;相反,一组重复的项目被附加到列表的末尾。我可以通过使用jQuery在渲染之前清除项目来解决这个问题,但这似乎是错误的。

这就是我现在所拥有的:

Item = Backbone.Model.extend({
    price: null,
});

Items = Backbone.Collection.extend({
    model: Item, 
    initialize: function () {
      this.add(new Item({ price: '$0.50' }));
      this.add(new Item({ price: '$0.60' }));
      this.add(new Item({ price: '$0.70' }));
    }
});

ItemView = Backbone.View.extend({
    tagName: 'li',
    initialize: function () {
      this.model.bind('change', this.render, this);
    },

    render: function () {
      var item_template = _.template($('#item-template').html(), { item: this.model }); 
      this.$el.html(item_template);
      return this;
    },

    events: {
      "click .copy-item": "copyItem",
    },

    copyItem: function (event) {
      var index = itemlistview.collection.indexOf(this.model);
      itemlistview.collection.add(new Item, { at: index + 1 });
    },
});

ItemListView = Backbone.View.extend({
    el: '#item-rows',
    initialize: function () {
      _.bindAll(this);
      this.collection = new Items();
      this.collection.bind('add', this.render);
      this.render();
    },
    render: function () {
      // It works if I uncomment the line below
      //$('.item-row').remove();
      var self = this;
      this.collection.each(function (item) {
        self.$el.append(new ItemView({ model: item }).render().el);
      });
      return this;
    },
});

var itemlistview = new ItemListView;

这是展示问题的jsFiddle

有没有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:4)

当你重新呈现整个事物时,你需要清除旧的渲染输入。

http://jsfiddle.net/Zk9NX/8/

更改项目列表视图

ItemListView = Backbone.View.extend({
    el: '#item-rows',
    initialize: function () {
      _.bindAll(this);
      this.collection = new Items();
      this.collection.bind('add', this.render);
      this.render();
    },
    render: function () {
      var self = this;
      this.$el.empty()
      this.collection.each(function (item) {
        self.$el.append(new ItemView({ model: item }).render().el);
      });
      return this;
    },
});