我想在应用中重复使用视图(之前打开的屏幕),但区域内容会消失。如何防止木偶这样做?
var app = new Backbone.Marionette.Application();
window.app = app;
app.addRegions({
root: 'body'
});
var View1 = Marionette.LayoutView.extend({
template: _.template('<div>View1<div class="sub"></div></div>'),
regions: {
sub: '.sub'
}
});
var View2 = Marionette.ItemView.extend({
template: _.template('<div>View2</div>')
});
var SubView = Marionette.ItemView.extend({
template: _.template('<div>SubView</div>')
});
var view1 = new View1();
var view2 = new View2();
var subView = new SubView();
app.root.show(view1, { preventDestroy: true });
view1.sub.show(subView, { preventDestroy: true });
setTimeout(function() {
app.root.show(view2, { preventDestroy: true });
setTimeout(function() {
app.root.show(view1, { preventDestroy: true });
}, 500);
}, 500);
答案 0 :(得分:1)
因此,preventDestroy不会阻止区域内的子视图仅被实际区域本身销毁。木偶的设计试图鼓励破坏视图并重新初始化它们,以便妥善处理清理工作。绕过这个问题的另一种方法是在显示视图时监听,然后显示子
app.listenTo(view1, "show", function () {
view1.sub.show(subView)
});
唯一的问题是子视图仍然被销毁,因此您可以覆盖subView的destroy方法以不破坏视图,这有点棘手以保持跟踪,因为现在您将不得不手动确保正确应用/删除绑定
var SubView = Marionette.ItemView.extend({
template: _.template('<div>SubView</div>'),
destroy: function () {
if (this.isDestroyed) {
return;
}
var args = [].slice.call(arguments);
this.triggerMethod.apply(this, ['before:destroy'].concat(args));
// mark as destroyed before doing the actual destroy, to
// prevent infinite loops within "destroy" event handlers
// that are trying to destroy other views
this.isDestroyed = false;
this.triggerMethod.apply(this, ['destroy'].concat(args));
// unbind UI elements????? well its not beng destoryed so probably don;t wantto do this
//unless you manually handle rebind the events
//this.unbindUIElements();
return this;
}
});
最终结果http://jsfiddle.net/ndr7262y/2/
但是这里更好的方法是在显示视图1时重新显示子视图
app.listenTo(view1, "show", function () {
var subView = new SubView();
view1.sub.show(subView)
});
现在你不必担心清理或覆盖destroy方法。 http://jsfiddle.net/ndr7262y/4/