【问题标题】:Backbone events with wildcards带通配符的主干事件
【发布时间】:2013-03-08 14:05:14
【问题描述】:

有没有办法监听命名空间的所有事件。所以当我听到这样的事件时:

app.vent.on('notification(:id)', function(type){console.lof(type)})

它会像这样监听所有事件:

app.vent.trigger('notification:info')
app.vent.trigger('notification:error')
app.vent.trigger('notification:success')

【问题讨论】:

    标签: javascript backbone.js


    【解决方案1】:

    没有。 Backbone 通常会触发一般的eventName 事件以及eventName:specifier 事件。这方面的一个例子是Model.change,它允许您监听所有更改,以及对单个字段的更改:

    model.on('change', this.onAnyPropertyChanged);
    model.on('change:name', this.onNamePropertyChanged);
    

    在您的代码中遵循此模式,您可以按如下方式触发您的事件:

    app.vent.trigger('notification', 'info');
    app.vent.trigger('notification:info');
    

    并收听一般事件:

    app.vent.on('notification', function(type){ 
      console.log(type);  //-> "info"
    }); 
    

    【讨论】:

      【解决方案2】:

      正如in this answer 所述,无法使用通配符监听事件。但是你可以听all 这会起作用:

      vent.on('all', function(evenName, options) {
        var type = evenName.split(/notification:/)[1];
        if (type) {
          console.log(type, options);
        }
      });
      

      【讨论】:

      • 这会起作用,但最好注意性能影响:如果您的应用程序大小不一且充分利用了中介 (vent),则可能会出现很多个事件被触发。 all 处理程序将看到大量流量,并可能导致实际性能下降。
      • 有趣...我怀疑这是否会在桌面网络上发挥作用,但你是对的——我会好奇它是如何在移动浏览器上运行的?特别是 ICS 之前的 Android 手机 (
      【解决方案3】:

      我已经写了这个助手:

      export default class EventsHelper {
        static triggerNamespacedEvent(eventBus, event, args) {
          event.split(':').reduce((previous, current) => {
            eventBus.trigger(previous, current);
            return `${previous}:${current}`;
          });
          eventBus.trigger(event, args);
        }
      }
      

      要在您的视图中使用它,您可以这样做:

      actionOne(argsOne){
          EventsHelper.triggerNamespacedEvent(this, 'click:chart:one', argsOne);
      }
      
      actionTwo(argsTwo){
          EventsHelper.triggerNamespacedEvent(this, 'click:chart:two', argsTwo);
      }
      

      要监听这些事件,你会这样做:

      //Listen for all clicks
      this.listenTo(view, 'click', (args) => {
          console.log(`clicked something: ${args}`); //output: clicked something: chart 
      });
      
      //Listen for all chart clicks
      this.listenTo(view, 'click:chart', (args) => {
          console.log(`clicked chart: ${args}`); //output: clicked chart: one 
      });
      
      //Listen for fully qualified event
      this.listenTo(view, 'click:chart:two', (args) => {
          console.log(`clicked chart two: ${args}`); //output: clicked chart two: evtArgs 
      });
      

      【讨论】:

        【解决方案4】:

        警告:监听自定义事件的事件命名空间可能不再有效。例如,这 工作:

          @listenTo @app, 'session', -> console.log ".listenTo `session` triggered"
          @listenTo @app, 'session:login_success', -> console.log ".listenTo `session:login_success` triggered"
        
          @app.on 'session', -> console.log ".on `session` triggered"
          @app.on 'session:login_success', -> console.log ".on `session:login_success` triggered"
        

        如果我在 @app 上触发 'session:login_success',则只会触发两个特定事件,而不是命名空间之一。

        相关github问题:https://github.com/documentcloud/backbone/issues/2558

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-13
          • 1970-01-01
          • 2011-10-13
          • 1970-01-01
          • 2013-06-17
          • 1970-01-01
          相关资源
          最近更新 更多