Marionette很棒,但有些事情可能会让人感到有些困惑。在我的初始页面加载中,我在Marionette.Application的区域中显示Marionette.Layout。但由于某种原因,点击事件被委派但实际上没有响应。如果我导航到另一个路径(删除布局视图)然后返回到路径(重新渲染视图),则事件处于活动状态。如果我导致视图连续渲染两次,那么它可以工作。也许我正在初始化这个系统。
var ListView = Backbone.Marionette.Layout.extend({
el: "#listView", // exists on DOM already
events: {
// this is what is supposed to work
// as well as events in my subviews
"click" : function() { console.log("clicked");}
});
var Router = Backbone.Router.extend({
initialize: function(options) {
this.app = options.app;
},
start: function(page) {
console.log("start...");
// with silent false this causes list() to be called
// and the view is rendered
// but the ListView does not get its events delegated
Backbone.history.start({
pushState: false,
silent: false
});
// only by running loadUrl here
// do I get the events delegated
// or by switching between other routes
// and coming back to 'list'
// but this is causing a second useless calling
// of list() re-rendering
console.log("loadUrl...");
Backbone.history.loadUrl(page);
// actually the events are not yet delegated at this point
// if I pause a debugger here.
// events only active after the Application finishes its initializers
},
routes: {
'list': 'list'
},
list: function() {
var lv = ListView({});
this.app.focus.show(lv)
}
});
var app = new Backbone.Marionette.Application();
app.addInitializer(function(options) {
this.router = new Router({app: this});
this.router.start();
});
app.addRegions({
// #focus does exist on the DOM
focus: "#focus",
});
app.start({});
我期望的替代性开始会起作用但遗憾的是
start: function(page) {
console.log("start...");
Backbone.history.start({
pushState: false,
silent: true // don't trigger the router
});
// call the router here via history
console.log("loadUrl...");
Backbone.history.loadUrl(page);
// causes page to be rendered correctly
// but events are not delegated
},
我已经使用调试器完成了所有操作,但仍然无法看到loadUrl的神奇效果是什么导致它工作。
我也试过将布局重新插入该区域:
app.focus.show(app.focus.currentView)
也许有一种不同的方式可以解决这个问题。
答案 0 :(得分:0)
不是100%肯定这是答案,但是......
如果您已经在DOM上存在元素,并且您尝试将视图附加到它们,并使用区域的attach
方法将该视图附加到区域:
list: function() {
var lv = ListView({});
this.app.focus.attach(lv)
}
{I}方法是专门为您想要使用现有DOM元素的情况创建的。相反,调用attach
将替换那里的内容,这可能导致jQuery事件被释放。
答案 1 :(得分:0)
添加
this.delegateEvents();
当Marionette关闭视图时,它也会解除事件的束缚。仅在初始化视图时委派事件。当您显示以前存储的视图时,您需要再次调用delegateEvents方法。
https://github.com/marionettejs/backbone.marionette/issues/714