1

Итак, у меня есть рабочий стол (родительский) и вид строки (ребенок).Модель дублирующей модели дублирует себя

добавить каждую строку с этим кодом

addOne: function (model, base) { 
    var view = new App.Views.file_manager_item({model: model}); 
    base.append(view.render()); 
}, 

renderList: function() { 
    var _this = this; 
    var collection = this.files_collection; 

    document.getElementById("content").innerHTML = this.templates.table(this.context); 

    this.$files = $(document.getElementById('files')); 

    collection.each(function(model) { 
     _this.addOne(model, _this.$files); 
    }); 
}, 

renderList обстрелян:

this.listenTo(this.files_collection, "change", this.renderList); 

App.Views.file_manager_item является

var File_manager_item = Backbone.View.extend({ 
    tagName: 'tr', 

    initialize: function() { 
     this.listenTo(this.model, "change", this.render); 
    }, 

    template: Template7.compile(document.getElementById("fm_item_template").innerHTML), 

    events: { 
     "click .check": "toggleCheck", 
    }, 

    toggleCheck: function() { 
     this.test = !this.test; 

     this.model.set({ 
      "checked": this.test 
     }); 
    }, 

    render: function() { 
     console.log(this.model) 
     var context = this.model.toJSON(); 
     this.el.innerHTML = this.template(context); 
     return this.$el; 
    }, 
}); 

и первым обратный ход утешать

child {cid: "c3", attributes: Object, ...} 
... 
... 
... 
... 
child {cid: "c11", attributes: Object, ...} 

после toggleCheck функция работает в два раза

child {cid: "c3", attributes: Object, ...} 
child {cid: "c3", attributes: Object, ...} 
... 
... 
... 
... 
child {cid: "c11", attributes: Object, ...} 

и после каждого изменения модели, добавить новый ребенка в консоли

child {cid: "c3", attributes: Object, ...} 

Почему модели дублируются?

+0

Это хороший вопрос, нет необходимости быть извините, на самом деле, вопрос никогда не должен включать в себя «извините за X», потому что это не имеет значения;) –

ответ

2

Модели не увеличиваются, это просто, что виды все еще живы, даже если они не на странице. Это своего рода утечка памяти. Существует несколько представлений элементов для одной и той же модели, которые прослушивают его событие change.

Хороший способ избежать этих утечек - сохранить ссылку на представление элемента при его создании, а затем вызвать .remove() на всех из них перед повторным рендерингом.

Ваше мнение пункт

var File_manager_item = Backbone.View.extend({ 
    tagName: 'tr', 
    template: Template7.compile(document.getElementById("fm_item_template").innerHTML), 

    events: { 
     "click .check": "toggleCheck", 
    }, 
    initialize: function() { 
     this.listenTo(this.model, "change", this.render); 
    }, 

    toggleCheck: function() { 
     this.test = !this.test; 
     this.model.set({ "checked": this.test }); 
    }, 

    render: function() { 
     console.log(this.model); 
     // use jQuery because it's already available 
     this.$el.html(this.template(this.model.toJSON())); 
     return this; // return this to chain calls 
    }, 
}); 

Тогда представление списка

var ListView = Backbone.View.extend({ 
    initialize: function() { 
     this.childViews = []; 
     this.listenTo(this.files_collection, "change", this.renderList); 
    }, 
    addOne: function(model) { 
     var view = new App.Views.file_manager_item({ model: model }); 
     this.childViews.push(view); 

     // this.$files is available here, there's no need to pass it around 
     this.$files.append(view.render().el); 
    }, 

    renderList: function() { 

     // same thing, use jQuery, it's useless to use the native API to them put it 
     // into a jQuery object, unless a marginal performance gain is the goal. 
     this.$("#content").html(this.templates.table(this.context)); 
     this.$files = this.$('#files'); 
     this.cleanup(); 

     // collection's each function is just a proxy to the underscore one. 
     this.files_collection.each(this.addOne, this); // use the context argument 
     return this; 
    }, 

    cleanup: function() { 
     _.invoke(this.childViews, 'remove'); 
     this.childViews = []; 
    }, 
}); 
+0

OK спасибо за этот ответный ответ, но у меня есть небольшая проблема. После ** очистки ** у меня все еще есть две копии ** ребенка **, это немного странно. –

+0

@ VasiliyRusin это может быть вызвано чем-то не в вашем вопросе. –

+1

И еще одна вещь, я не хочу, чтобы это было необходимо, но в ** очистке ** функция должна добавить * this.childViews = [] * –