Backbone.js collection image showing duplicate elements

In my Backbone.js application, I need to be able to insert new items between existing items in the collection. The examples I've found so far on the internet seem to suggest that new items should be added to the end of the collection. This doesn't work for my purposes, so I decided to retrain the entire collection when adding a new item.

However, the original items are not removed from the view; instead, the duplicate set of items is added to the end of the list. I can work around this by using jQuery to clear the elements before rendering, but that seems to be wrong.

Here's what I have right now:

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;

      

And here's a jsFiddle that demonstrates the problem.

Is there a better way to handle this?

+3


source to share


1 answer


As you reengineer everything, you need to clear the old rendered inputs.

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



Changed ItemListView

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;
    },
});

      

+4


source







All Articles