防止Backbone事件多次触发,如何检查事件是否已经注册?

yke*_*kel 2 backbone.js

在我的路由器对象中,我创建了一个事件对象以在我的视图中共享

我将事件对象传递给我的视图

我将事件注册到这个共享对象

var productCatalogView = Backbone.View.extend({
      initialize: function (options) {
                     //bind alert event to sharedEvents
                    options.sharedEvents.bind("alert", this.alert,this);
                },
      alert: function () {
                    alert('alerted');
                }
    });
Run Code Online (Sandbox Code Playgroud)

//以下视图触发警报事件

 var testView = Backbone.View.extend({

            initialize: function (options) {
                this.sharedEvents = options.sharedEvents;
            },
            events: {
                 'click #test': 'triggerAlert'
            },

            triggerAlert: function (e) {
                this.sharedEvents.trigger("alert", null);

            }           

        });
Run Code Online (Sandbox Code Playgroud)

问题:我遇到的问题是,当我第一次点击触发警报事件(第二个视图)的按钮时,警报事件被调用一次(好),这会导致第一个视图通过触发重新呈现路由传递搜索参数,因此创建第一个视图并再次绑定sharedEvents,因此当我第二次触发警报事件时,它会被触发两次(坏),下次我重复相同的过程,它会被触发3次,等等等等.我想它与第一个视图中的事件绑定有关,它不止一次出现,即每次初始化视图时(如果我是正确的)请问如何才能使事件的绑定发生一次.

这是我的路由器,它显示了我如何初始化视图:

var Router = Backbone.Router.extend({

    sharedEvents:_.extend({},Backbone.Events),

    catalog: function (id) {

       //....unecessary code left out

        var productView = new ProductView({sharedEvents:this.sharedEvents});

            this.renderView(productView);
            this.renderView(new testView({sharedEvents: this.sharedEvents }));
       }

      renderView: function (view) {
                if (null != this.currentView) {
                    this.currentView.undelegateEvents();
                    // this.currentView.remove();
                }
                this.currentView = view;
                this.currentView.render();
            }

});
Run Code Online (Sandbox Code Playgroud)

我试过这个解决方案,但问题仍然存在,谢谢

Jus*_*tin 5

尝试使用Backbone.Events的listenTo方法而不是bind方法.然后,在你的renderView()电话中,this.currentView.remove而不是this.currentView.undelegateEvents.

理由:

我相信你的renderView()方法,你正在使用undelegateEvents()它认为它释放你的视图创建的所有事件监听器.它释放绑定到视图$el元素的事件.但是,remove()在视图上使用会释放绑定到$el使用this.listenTo()(和this.listenOnce())创建的事件的事件.

现在,一旦您渲染另一个视图,旧的currentView将被正确释放,您将只获得一个警报.