1

父对象的每个“子”都需要订阅事件聚合器中的固定事件:例如:

var dispatcher = EventAggregator.create();

应用程序中有多个“视图”,所有视图都必须订阅关闭事件。使用主干:

Backbone.View.prototype.close = function(){
  //close logic
};

现在每个视图都需要订阅事件聚合器上的“关闭”事件,即var dispatcher不需要显式调用方法来完成它。那不是经常说:

dispatcher.on('close', this.close)或者ParentView.prototype.someMethod.apply()

在作为 Backbone.View 实例的每个视图中,有没有办法让所有视图自动订阅close调度程序上的事件?

像这样的东西可以工作吗:(在我的情况下似乎没有,因为this绑定到窗口:)

Backbone.View.prototype.subscribeClose: (function(){
 dispatcher.on('close',this.close);
})();

由于this绑定到窗口,因此失败。有什么更好的方法来解决这个问题,还是我必须手动调用父/原型方法以确保订阅总是发生?JS中是否有我可能不知道的“另一种”方式?

更新:添加小提琴这两个视图都应该在“olay”上触发,但只有一个subscribeOnClose添加到原型的视图似乎工作正常(根据 Dan 的回答进行实验)。但是,这两个视图都不响应触发器。现在只是用模型模拟触发器。

4

1 回答 1

1

更新

I didn't want to bring this out unless really necessary, but if you really want this to apply to all view instances, without the need to have them descend from your own custom base view class, you can try something like this (overriding Backbone.View, the built-in base view class constructor):

http://jsfiddle.net/D9gR7/5/

$( document ).ready( function () {

  // Create your actual object here

  var dispatcher = _.clone( Backbone.Events );

  ( function () {

    var ctor = Backbone.View;

    Backbone.View = Backbone.View.extend( {

      constructor : function ( options ) {

        ctor.apply( this, arguments );

        dispatcher.on( 'close', this.close, this );

      },
      // constructor


      close : function () {

          console.log( this.cid );

      }
      // close

    } );

    Backbone.View.prototype.constructor = Backbone.View;

  } )();


  var View = Backbone.View.extend( {} );


  var views = [];

  var i;

  for ( i = 0 ; i < 10 ; ++i ) {

    views.push( new Backbone.View );

  }


  for ( i = 0 ; i < 10 ; ++i ) {

    views.push( new View );

  }

  dispatcher.trigger( 'close' );

} );

Original Answer

There are a bunch of issues with your code. What about something like this (see the console for output, obviously)? I think this is pretty much what you're going for. You'd just need to make sure you call the parent initialize() when you override the method in sub classes. Also, if you want to completely blow away the view instances at some point, make sure you call dispatcher.off( null, null, view_instance ).

http://jsfiddle.net/D9gR7/

$( document ).ready( function () {

  // Create your actual object here

  var dispatcher = _.clone( Backbone.Events );

  var View = Backbone.View.extend( {

    initialize : function ( options ) {

      dispatcher.on( 'close', this.close, this );

    },


    close : function () {

      console.log( this.el.id );

    }

  } );


  var Some_Kind_Of_View = View.extend( {

    initialize : function ( options ) {

      View.prototype.initialize.apply( this, arguments );

      // ...

    }

  } );


  var view1 = new View( {

    el : $( "#MyDiv" )[0],

  } );


  var view2 = new Some_Kind_Of_View( {

    el : $( "#MyDiv2" )[0]

  } );


  dispatcher.trigger( 'close' );

} );

Some issues with your example code:

var V1 = Backbone.View.extend({

    // JMM: If you pass `el` to `extend()`, any instances you create
    // from the class will be tied to the same DOM element, unless
    // you pass a different `el` to the view constructors. Maybe
    // that's what you want.

    el: '#MyDiv',

    initialize: function() {
        var self = this;

        // JMM: You're assigning `undefined` to this prototype
        // property. And you're trying to register the
        // return value of self.alert() (`undefined`) as
        // the handler for the `olay` event.

        Backbone.View.prototype.subOnClose = (function(){
            model.on('olay',self.alert('olay'));
        })();
    },

    alert: function(s) {
        alert('V1 -->' + s);
    }
});
于 2012-08-14T22:01:35.417 回答