在the Marionette docs for CompositeView
中,它描述了覆盖appendHTML
以自定义目标,应使用jQuery的append
添加每个itemView
的HTML。
使用类似的思路,如果我有两个ItemView
个对象,则Parent
和Child
以及Parent
的模板都有一个空目标{{ 1}}我想在其中注入<div class="target"></div>
的模板。我可以在Child
中使用jQuery的html
和onRender
来执行此操作。
在Parent
生命的整个过程中,我想用其他东西清除或替换Parent
的内容。如果我以后想要将.target
重新呈现为Child
(因为它可能会根据自第一次渲染后的用户交互呈现不同的模板),我可以使用相同的逻辑:
.target
模板html
Child
的内容设置为.target
的{{1}}
醇>
问题是,一旦发生Child
的第二次呈现,el
视图中的任何事件似乎都会丢失。
以下是我所描述的具体例子:
HTML
Child
Javascript
Child
首先点击<script type="template" id="parent">
<p><a class="re-render" href="javascript://">Re-Render</a></p>
<div class="target"></div>
</script>
<script type="template" id="child">
<p><a href="javascript://">The Link</a></p>
</script>
<div id="main"></div>
中的链接效果很好。在var Views = {};
Views.Child = Backbone.Marionette.ItemView.extend({
template: '#child',
events: {
'click a': 'changeBg'
},
changeBg: function() {
this.$el.css('background-color', '#'+Math.floor(Math.random()*16777215).toString(16));
}
});
Views.Parent = Backbone.Marionette.ItemView.extend({
template: '#parent',
childView: undefined,
ui: {
target: '.target'
},
events: {
'click .re-render': 'onRender'
},
initialize: function() {
this.childView = new Views.Child();
},
onRender: function() {
this.childView.render();
this.ui.target.html(this.childView.el);
this.childView.$el.css('background-color', 'transparent');
}
});
var App = new Backbone.Marionette.Application();
App.addRegions({
mainRegion: "#main"
})
App.mainRegion.show(new Views.Parent());
中点击重新渲染后,Child
点击事件永远不会重新应用于新呈现的Parent
模板版本。 如何确保每次呈现Child
时都会重新应用Child
模板的事件?
您可以为 here 找到一个jsFiddle。
答案 0 :(得分:1)
您应该在子视图重新渲染后调用.delegateEvents()
:
onRender: function() {
this.childView.render();
this.ui.target.html(this.childView.el);
this.childView.delegateEvents();
this.childView.$el.css('background-color', 'transparent');
}
这是如何在vanilla Backbone中解决它。我不知道Backbone.Marionette是否有另一种处理问题的方法,但在Marionette术语中,您可以将delegateEvents
调用添加到子视图的onRender
方法中以封装重新呈现。
Views.Child = Backbone.Marionette.ItemView.extend({
//...
onRender: function() {
this.delegateEvents();
}
});