1

그래서 테이블 뷰 (상위)행 뷰 (하위)이 있습니다.백본 컬렉션 모델 자체 복제

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

는이 코드

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에 의해 해고를 모든 행을 추가

및 첫 번째 실행 복귀 toggleCheck 기능

child {cid: "c3", attributes: Object, ...} 
child {cid: "c3", attributes: Object, ...} 
... 
... 
... 
... 
child {cid: "c11", 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

이 특별한 답변을 주셔서 감사합니다.하지만 약간의 문제가 있습니다. ** 정리 후 ** 나는 여전히 ** child **의 복사본을 가지고 있습니다. 그것은 약간 이상합니다. –

+0

@VasiliyRusin 귀하의 질문에없는 것으로 인해 발생할 수 있습니다. –

+1

그리고 한가지 더, 나는 필요 없다고 단정하지만, ** 정리 ** 함수는 * this.childViews = [] * –