Backbone.js에서 뷰 및 모델 폐기
필요하지 않을 때 모델 / 뷰 인스턴스를 처리하는 가장 효율적인 방법은 무엇입니까?
일반적으로 모든 것이 컨트롤러 / 라우터에 넣습니다. 어떤 뷰를 생성해야하며 어떤 모델을 제공해야 할 것인지 결정하는 것입니다. 일반적으로 다른 사용자 작업 또는 경로에 해당하는 몇 가지 가지 함수가 사용하는 것이 실행될 때마다 새 뷰 인스턴스를 만듭니다. 물론 이전에 뷰 인스턴스에 저장 한 내용을 제거해야합니다. 그러나 일부 뷰가 DOM 이벤트 처리기는 자체적으로 유지되고 식별하게 바인딩 해제되지 않아 해당 인스턴스가 유지되는 상황이 있습니다. 예를 들어 el (DOM 표현)이 분리되거나 DOM에서 버려 질 때보기 인스턴스를 파괴하는 방법이 좋겠습니다.
당신은 올바른 길을 가고 있습니다. 뷰의 수명주기를 제어하는 개체가 있어야합니다. 나는 관점에 두는 것을 좋아하지 않는다. 나는 별도의 개체를 만드는 것을 좋아합니다.
해야 할 필요가있을 때 이벤트의 바인딩을 해제하는 것입니다. 이렇게 모든 뷰에 "close"메서드를 생성하여 모든 항목의 수명주기를 제어하는 개체를 사용하여 항상 close 메소드를 호출하는 것이 좋습니다.
예를 들면 :
function AppController(){
this.showView = function (view){
if (this.currentView){
this.currentView.close();
}
this.currentView = view;
this.currentView.render();
$("#someElement").html(this.currentView.el);
}
}
이 시점에서 AppController의 인스턴스를 하나만 갖도록 코드를 설정하고 항상 appController.showView(...)
라우터 또는 #someElement
화면 부분에 보기를 표시해야하는 다른 코드에서 호출 합니다.
( "AppView"(앱의 주요 부분을 실행하는 백본보기)를 사용하는 매우 간단한 백본 앱의 또 다른 예가 있습니다. 여기 : http://jsfiddle.net/derickbailey/dHrXv/9/ )
이 방법은 close
기본적으로 뷰에 존재하지 않습니다. close 메소드에 항상 두 가지가 있습니다. this.unbind()
및 this.remove()
. 이 외에도 뷰를 모델 또는 컬렉션 이벤트에 바인딩하는 경우 메서드에서 바인딩을 해제해야합니다.
예를 들면 :
MyView = Backbone.View.extend({
initialize: function(){
this.model.bind("change", this.modelChanged, this);
},
modelChanged: function(){
// ... do stuff here
},
close: function(){
this.remove();
this.unbind();
this.model.unbind("change", this.modelChanged);
}
});
이 DOM에서 모든 이벤트 (를 통해 this.remove()
), 뷰 자체가 발생하는 모든 이벤트 (를 통해 this.unbind()
) 및 뷰가 모델에서 바인딩 된 이벤트 (를 통해 ) 를 정리합니다
this.model.unbind(...)
.
더 간단한 방법은 Backbone.View 객체 정의 메소드를 추가하는 것입니다.
Backbone.View.prototype.close = function () {
this.$el.empty();
this.unbind();
};
위의 코드를 사용하여 다음을 수행 할 수 있습니다.
var myView = new MyView();
myView.close();
천천히 요.
나는 항상 뷰를 뷰를 폭탄하고 모델을 핵합니다. 모델을 주변에두면 뷰가 할당 해제 할 수 있습니다. 모델은 바인딩 해제되지 않은 경우 뷰에 대한 참조를 찾을 수 없습니다.
Backbone ~ 0.9.9부터 model.on ()이 아닌 view.listenTo ()로 모델을 바인딩하면 제어 반전을 통해 쉽게 정리할 수 있습니다 (모델과 반대되는 제어 바인딩보기). view.listenTo ()를 사용하여 바인딩하는 경우 view.stopListening () 또는 view.remove ()를 호출하면 모든 바인딩이 제거됩니다. model.off (null, null, this)를 호출하는 것과 유사합니다.
반자동으로 하위 뷰를 호출하는 닫기 기능으로 뷰를 확장하여 뷰를 정리하고 싶습니다. 뷰는 부모의 속성에 하위 참조되거나 childViews []라는 부모의 배열에 추가되어야합니다.
제가 사용하는 기능은 ..
// fired by the router, signals the destruct event within top view and
// recursively collapses all the sub-views that are stored as properties
Backbone.View.prototype.close = function () {
// calls views closing event handler first, if implemented (optional)
if (this.closing) {
this.closing(); // this for custom cleanup purposes
}
// first loop through childViews[] if defined, in collection views
// populate an array property i.e. this.childViews[] = new ControlViews()
if (this.childViews) {
_.each(this.childViews, function (child) {
child.close();
});
}
// close all child views that are referenced by property, in model views
// add a property for reference i.e. this.toolbar = new ToolbarView();
for (var prop in this) {
if (this[prop] instanceof Backbone.View) {
this[prop].close();
}
}
this.unbind();
this.remove();
// available in Backbone 0.9.9 + when using view.listenTo,
// removes model and collection bindings
// this.stopListening(); // its automatically called by remove()
// remove any model bindings to this view
// (pre Backbone 0.9.9 or if using model.on to bind events)
// if (this.model) {
// this.model.off(null, null, this);
// }
// remove and collection bindings to this view
// (pre Backbone 0.9.9 or if using collection.on to bind events)
// if (this.collection) {
// this.collection.off(null, null, this);
// }
}
그러면 다음과 같이 뷰가 선언됩니다 ..
views.TeamView = Backbone.View.extend({
initialize: function () {
// instantiate this array to ensure sub-view destruction on close()
this.childViews = [];
this.listenTo(this.collection, "add", this.add);
this.listenTo(this.collection, "reset", this.reset);
// storing sub-view as a property will ensure destruction on close()
this.editView = new views.EditView({ model: this.model.edits });
$('#edit', this.el).html(this.editView.render().el);
},
add: function (member) {
var memberView = new views.MemberView({ model: member });
this.childViews.push(memberView); // add child to array
var item = memberView.render().el;
this.$el.append(item);
},
reset: function () {
// manually purge child views upon reset
_.each(this.childViews, function (child) {
child.close();
});
this.childViews = [];
},
// render is called externally and should handle case where collection
// was already populated, as is the case if it is recycled
render: function () {
this.$el.empty();
_.each(this.collection.models, function (member) {
this.add(member);
}, this);
return this;
}
// fired by a prototype extension
closing: function () {
// handle other unbinding needs, here
}
});
참고 URL : https://stackoverflow.com/questions/7379263/disposing-of-view-and-model-objects-in-backbone-js
'ProgramingTip' 카테고리의 다른 글
프로그래밍 기술을 향상시키기위한 아주 작은 프로그램? (0) | 2020.11.21 |
---|---|
10 개의 데이터 구조에서 10 개의 함수보다 하나의 데이터 구조에서 100 개의 함수가 작동하는 것이 더 좋은 이유 (0) | 2020.11.21 |
새 사용자 정의 컨트롤을 도구 상자 나 새 Winform에 어떻게 추가 할 수 있습니까? (0) | 2020.11.21 |
C ++에서 돌아가는 가장 좋은 방법은 무엇입니까? (0) | 2020.11.21 |
루비에서 to_s 대 to_str (그리고 to_i / to_a / to_h 대 to_int / to_ary / to_hash) (0) | 2020.11.21 |