Backbone视图事件无法绑定到多个模板的问题求助
这个问题的核心在于Backbone的事件委托机制是绑定在视图的el元素上的——只有当目标元素是el的后代时,事件冒泡才能被视图捕获并处理。你直接用全局$(".attachDetails")渲染的模板,要么不在主视图el的范围内,要么没有通过视图的上下文去操作,导致事件委托覆盖不到。
下面给你几个可行的解决方案:
1. 确保子模板容器在视图el范围内,并用视图上下文操作
首先检查.attachDetails是否是.prodDetailContainer(也就是你视图的el)的子元素。如果是的话,把你渲染子模板的代码改成用视图的jQuery对象来操作,而不是全局jQuery:
// 把全局$改成视图的this.$,确保操作的是el内部的元素 this.$(".attachDetails").html(this.prodDetailsTemplate(selAgg.toJSON()));
这样渲染出来的.future-inv元素就在视图el的后代链里,Backbone的事件委托(绑定在el上)就能正常捕获到点击事件,不需要额外修改events配置。
2. 手动重新触发事件委托绑定
如果.attachDetails不在视图el范围内,你可以在渲染完子模板后,手动调用Backbone视图的delegateEvents()方法,它会重新把events里的事件绑定到视图的el上(如果子模板元素在el外的话,这个方法没用,还是建议用第一种方法):
$(".attachDetails").html(this.prodDetailsTemplate(selAgg.toJSON())); // 重新绑定所有事件委托 this.delegateEvents();
注意:这个方法会重新绑定所有events里的事件,虽然能解决问题,但有点冗余,优先推荐第一种方案。
3. 扩展视图的el范围
如果.attachDetails和.prodDetailContainer是同级元素,你可以把视图的el设置为它们共同的父容器,这样两个模板的元素都在视图el范围内:
// 假设共同父容器类是.prod-page-container this.setElement($(".prod-page-container")); // 渲染主模板 this.$(".prodDetailContainer").html(this.templateDesktop(this.dataSet.toJSON())); // 渲染子模板 this.$(".attachDetails").html(this.prodDetailsTemplate(selAgg.toJSON()));
这样所有元素都在视图el下,事件委托自然能覆盖到。
原理补充
Backbone的events配置本质是用jQuery的delegate()(或现代的on())方法,把事件绑定在视图的根el上,然后通过选择器匹配触发事件的子元素。如果目标元素不在el的后代树里,事件冒泡到el时就匹配不到对应的选择器,所以不会触发绑定的方法。
内容的提问来源于stack exchange,提问作者Akash Kaundinya

