http://jsfiddle.net/feronovak/8svqX/
这没有什么特别的,真的是让我了解如何正确地调用单独的视图,所以他们不会触发以前的点击方法.现在我在#BoxSearch中生成两个视图,第二个View覆盖表单.当我点击按钮搜索它也生成警报doSearch SearchLocation.我期待看到只有警惕的doSearch SearchLatitude.我做错了什么?
var Geo = { Views: {},Templates: {} }; Geo.Templates.SearchLocation = _.template( $("#tpl-search-location").html()); Geo.Templates.SearchLatitude = _.template( $("#tpl-search-latitude").html()); Geo.Views.SearchLocation = Backbone.View.extend({ initialize: function() { this.render(); },el: $("#BoxSearch"),template: Geo.Templates.SearchLocation,render: function() { $(this.el).html(this.template); },events: { "click input[type=button]": "doSearch" },doSearch: function(e) { e.preventDefault(); alert('doSearch SearchLocation'); } }); Geo.Views.SearchLatitude = Backbone.View.extend({ initialize: function() { this.render(); },template: Geo.Templates.SearchLatitude,doSearch: function(e) { e.preventDefault(); alert('doSearch SearchLatitude'); } }); $(document).ready(function(e) { var searchLocation = new Geo.Views.SearchLocation(); var searchLatitude = new Geo.Views.SearchLatitude(); });
解决方法
>将视图附加到DOM元素
>将另一个视图附加到同一个DOM元素
>您在DOM元素上触发一个事件(或者更糟的是,触发两个视图所听到的其他事件)
>这两种观点都对他们的事件处理程序起火,经常会造成严重破坏.
正如@machineghost所指出的那样,您的代码中没有解除第一个视图的绑定,因此这两个视图都附加到#BoxSearch,这两个视图都将响应点击事件.有几种方法:
>你可以在事件处理程序中调用e.stopPropagation()(docs)(我想这是你试图用e.preventDefault()).这将阻止事件触发后冒泡,因此最后定义的视图将捕获它.这有效,但请注意,您仍然会看到两个视图,而过时的鬼影可能会有其他副作用.
>您可以让每个视图渲染自己的DOM元素,并使用.BoxSearch类,然后在不再需要的视图上调用view.remove().这可能是最干净的选项,但这意味着即时创建大部分的DOM,与HTML中的编码相比,它的价格要贵一些,难以管理.
>您可以给每个视图一个清除方法,例如.clear()或.exit(),它可以调用view.undelegateEvents()和view.stopListening().当您完成视图时,请确保您调用此方法.
如果你小心确保它被调用,并确保它清除所有需要清除的东西,那么它工作得很好.