marionetteItemView 子视图,未触发事件
marionetteItemView Childview, events not triggered
所以这是 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>
子视图呈现在父视图之上,但没有触发任何事件(保存、丢弃、上传)。
任何hints/ideas?
谢谢。
.delegateEvents()
绑定事件的方式是委托给视图的 el
。在 source 你会看到这个:
delegate: function(eventName, selector, listener) {
this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
},
如您所见,在视图的 $el
上调用了 jQuery .on()
。如果将 selector
参数传递给 .delegate()
(例如 .js-save
),则选择器的事件将委托给其包含视图的 el
.
您覆盖 .render()
的方式是您选择用“全能”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。 您想将非模型数据加载到模板中。
1。设置视图 el
Backbone 将采用现有的 DOM 元素作为视图的 el
。只需在视图实例化时传入选择器或 jQuery 对象,
var childView = new ChildView({ el: $container });
Marionette .render()
方法会将视图附加到 $container
。
2。将非模型数据传递给您的模板
Marionette 有这个方便的视图实用程序,templateHelpers
,它允许您将数据放入模板渲染器的范围内。数据可以是任何 JS 对象,包括函数。只需在您的视图中包含 属性。
templateHelpers: function () {
return {
img: function(){
return 'http://some-domain.com/img/" + this.id;
},
id: this.id
};
}
});
其中,在此版本中 templateHelper
this
是视图的上下文。
所以这是 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>
子视图呈现在父视图之上,但没有触发任何事件(保存、丢弃、上传)。
任何hints/ideas?
谢谢。
.delegateEvents()
绑定事件的方式是委托给视图的 el
。在 source 你会看到这个:
delegate: function(eventName, selector, listener) {
this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
},
如您所见,在视图的 $el
上调用了 jQuery .on()
。如果将 selector
参数传递给 .delegate()
(例如 .js-save
),则选择器的事件将委托给其包含视图的 el
.
您覆盖 .render()
的方式是您选择用“全能”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。 您想将非模型数据加载到模板中。
1。设置视图 el
Backbone 将采用现有的 DOM 元素作为视图的 el
。只需在视图实例化时传入选择器或 jQuery 对象,
var childView = new ChildView({ el: $container });
Marionette .render()
方法会将视图附加到 $container
。
2。将非模型数据传递给您的模板
Marionette 有这个方便的视图实用程序,templateHelpers
,它允许您将数据放入模板渲染器的范围内。数据可以是任何 JS 对象,包括函数。只需在您的视图中包含 属性。
templateHelpers: function () {
return {
img: function(){
return 'http://some-domain.com/img/" + this.id;
},
id: this.id
};
}
});
其中,在此版本中 templateHelper
this
是视图的上下文。