如何在对象的原型中使用自动运行的函数为JavaScript中的所有子项自动运行?

时间:2012-08-14 19:17:30

标签: javascript backbone.js

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

var dispatcher = EventAggregator.create();

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

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

现在每个视图都需要在事件聚合器(即var dispatcher)上订阅“close”事件,而无需显式调用方法来执行此操作。这不是经常说:

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中是否存在我可能不知道的“另一种”方式?

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

1 个答案:

答案 0 :(得分:1)

更新

除非确实有必要,否则我不想将其删除,但是如果你真的想要将它应用于所有视图实例,而不需要让它们从你自己的自定义基础视图类中下载,您可以尝试这样的事情(覆盖Backbone.View,内置的基本视图类构造函数):

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' );

} );

原始答案

您的代码存在许多问题。这样的事情(显然,请参阅控制台输出)?我认为这几乎就是你想要的。在覆盖子类中的方法时,您只需要确保调用父initialize()。此外,如果您想在某个时刻完全吹走视图实例,请务必致电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' );

} );

示例代码存在一些问题:

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);
    }
});