所以这是ParentView上的代码: 相关方法:
openChildView: function(){
var childView = new ChildView({
container: $container //container where the child map should be appended
});
childView.show();
}
这是ChildView的代码:
ChildView = Marionette.ItemView.extend({
template: _.template($(templates_c).filter('#my_child_view_template').html()),
ui: {
saveButton: 'button.js-save',
uploadButton: 'button.js-upload',
deleteButton: 'button.js-discard'
},
events: {
'click @ui.saveButton': function() {
log.debug('save');
},
'click @ui.uploadButton': function() {
log.debug('upload');
},
'click @ui.deleteButton': function() {
log.debug('delete');
}
},
show: function() {
this.render();
},
initialize: function(){
this.container = this.options.container;
this.id = this.options.id;
},
remove: function(){
// Don't know yet if this is the proper way, but for now it works
this.container.find('.container-child-view').remove();
},
render: function(){
this.container.append(this.template({
id: this.id,
img: '...'
}));
log.debug('on render');
this.bindUIElements();
this.delegateEvents();
return this;
}
});
这是ChildView模板的代码:
<script type="text/x-template" id="my_child_view_template">
<div class="block container-child-view">
<div class="block-title">
<h4><%= id %></h4>
</div>
<div class="img">
<img src="<%= imgUrl %>">
</div>
<div class="row text-center">
<div class="btn-group btn-group-xs">
<button id="discard" type="button" class="js-discard btn btn-alt btn-warning"><i class="fa fa-times-circle"></i> Cancel</button>
<button id="upload" type="button" class="js-upload btn btn-alt btn-primary"><i class="fa fa-upload"></i> Upload</button>
<button id="save" type="button" class="js-save btn btn-alt btn-primary"><i class="fa fa-save"></i> Save</button>
</div>
</div>
</div>
</script>
childView正在父视图上呈现,但没有触发任何事件(保存,丢弃,上传)。
任何提示/想法?
感谢。
答案 0 :(得分:1)
.delegateEvents()
绑定事件的方式是委托给视图el
。在source中,您会看到:
delegate: function(eventName, selector, listener) {
this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
},
正如您所看到的,在视图.on()
上调用了jQuery $el
。如果将selector
参数传递给.delegate()
(比如说.js-save
),则将选择器的事件委托给其包含的视图el
。< / p>
您覆盖.render()
的方式,您选择替换&#34; all-mighty&#34; this.el
this.container
。调用this.delegateElements()
仍然会调用.delegate()
来对this.el
进行绑定,而您的视图实际上位于this.container
。视图事件正在冒泡到未绑定的容器。
快速修复可能会覆盖渲染,如下所示:
render: function(){
this.container.append(this.template({
id: this.id,
img: '...'
}));
log.debug('on render');
this.bindUIElements();
// .setElement is an internal method that will
// make your container the view's el and will call
// .delegateEvents on this new el
this.setElement();
return this;
}
});
除非我还为您提供了更加面向框架的解决方案,否则我可能无法称自己为正直的Marionette社区居民。在我看来,您已覆盖.render
因为您希望 1。将ItemView
渲染为特定的包含元素且 2。您希望将非模型数据加载到模板中。
el
Backbone将为视图的el
采用现有的DOM元素。只需在视图的实例化中传入选择器或jQuery对象,
var childView = new ChildView({ el: $container });
Marionette .render()
方法会将视图附加到$container
。
Marionette拥有这个方便的视图实用程序templateHelpers
,可让您将数据放在模板渲染器的范围内。数据可以是任何JS对象,包括函数。只需在您的视图中包含该属性即可。
templateHelpers: function () {
return {
img: function(){
return 'http://some-domain.com/img/" + this.id;
},
id: this.id
};
}
});
其中,templateHelper
this
的此版本是视图的上下文。