我真的不明白Backbone应该如何处理在HTML插入DOM之前在HTML上注册事件处理程序的常见场景。
大多数Backbone视图都是这样的:
var PortalView = Backbone.View.extend({
events: {
'click #logout-li-id': 'onClickLogout' //1 (doesn't work)
},
initialize: function (opts) {
var self = this;
$('#logout-li-id').on('click', function (event) { //2 (doesn't work because '#logout-li-id' is not in the DOM yet
event.preventDefault();
alert(event);
});
},
render: function () {
var self = this;
var template = allTemplates['templates/portalTemplate.ejs'];
var ret = EJS.render(template, {});
$('#main-div-id').html(ret);
$('#logout-li-id').on('click', function (event) { //3 works!
event.preventDefault();
alert(event);
});
return this;
},
onClickLogout: function(event){
alert(event);
}
});
正如您在上面所看到的,我已经标记了3个类似的调用来在DOM元素'#logout-li-id'上注册事件处理程序 - 问题是在DOM元素上注册回调的唯一成功调用在渲染函数(调用#3)中,在之后出现,这个Backbone视图被插入到DOM中。因此,在Backbone视图的事件对象中声明键的标准方法不起作用!那么用Backbone做这件事的正确方法是什么?
答案 0 :(得分:3)
Backbone期望视图将通过events
哈希处理的事件是视图el
的子节点(即视图的根DOM元素)。看起来你可能没有将这个视图附加到你正在听的DOM元素的父元素 - $('#main-div-id')
是视图的el
的孩子吗?
这里的标准方法是:
var PortalView = Backbone.View.extend({
// Associate this view with the element it will manage
el: '#main-div-id',
events: {
'click #logout-li-id': 'onClickLogout'
},
render: function () {
var template = allTemplates['templates/portalTemplate.ejs'];
var ret = EJS.render(template, {});
// Render to this view's element
this.$el.html(ret);
}
});
更多详细信息:events
哈希通过将委派的事件处理程序添加到视图的DOM节点来工作。实质上,视图的DOM树中的每次单击都将调用一个处理程序,该处理程序检查事件目标是否与给定的选择器匹配。如果是这样,它会将事件传递给您指定的view方法。但这只有在您单击的元素位于视图的DOM树中时才有效 - 否则,视图的DOM将永远不会获取事件,并且永远不会调用事件处理程序。