Backbone.js的:如何从事件解除绑定,在模型中移去(Backbone.js: how to

2019-06-24 03:47发布

在骨干网我们有一个使用的事件聚合,位于应用程序window.App.Events现在,在很多意见,我们绑定到该聚合,和我手动写了一个视图中的破坏作用,它处理从事件聚集解除绑定然后除去图。 (而不是直接除去视图)。

现在,有我们需要这个功能,以及某些型号的,但我无法弄清楚如何解决它。

某些型号需要绑定到特定的事件,但也许我错了,但如果我们删除它保持在内存中集合的模式,由于这些绑定的事件聚合,其依然存在。

没有真正模型上删除功能,如一种观点。 所以我怎么会TACKE呢?

EDIT上请求,一些代码的例子。

App = {
    Events: _.extend({}, Backbone.Events)
};

var User = Backbone.Model.extend({

    initialize: function(){
        _.bindAll(this, 'hide');
        App.Events.bind('burglar-enters-the-building', this.hide);
    },

    hide: function(burglarName){
        this.set({'isHidden': true});
        console.warn("%s is hiding... because %s entered the house", this.get('name'), burglarName);
    }

});

var Users = Backbone.Collection.extend({

    model: User

});

var House = Backbone.Model.extend({

    initialize: function(){
        this.set({'inhabitants': new Users()});
    },

    evacuate: function(){
        this.get('inhabitants').reset();
    }

});



$(function(){

    var myHouse = new House({});

    myHouse.get('inhabitants').reset([{id: 1, name: 'John'}, {id: 1, name: 'Jane'}]);

    console.log('currently living in the house: ', myHouse.get('inhabitants').toJSON());

    App.Events.trigger('burglar-enters-the-building', 'burglar1');

    myHouse.evacuate();

    console.log('currently living in the house: ', myHouse.get('inhabitants').toJSON());

    App.Events.trigger('burglar-enters-the-building', 'burglar2');

});​

查看的jsfiddle(在控制台输出)中动作的代码: http://jsfiddle.net/saelfaer/szvFY/1/

你可以看到,我不绑定到模型上的事件,但事件聚合。 从模型本身解除绑定的事件,是没有必要的,因为如果它删除没有人会再次触发它的事件。 但eventAggregator总是在的地方,为了便于传递活动在整个应用程序。

代码示例显示,即使当它们被从集合中删除,他们没有住的房子了,但是当小偷进入屋内仍执行隐藏命令。

Answer 1:

我看到,即使在结合事件方向这样Object1 - >收听- > Object2的它,以拆下来Object1失去任何活着的参考。

而当看到聆听模式remove事件是不是一个解决方案,由于它不是在一个名为Collection.reset()调用,然后我们有两个解决方案:

1.覆盖正常收集清理

作为@dira最高审计机关在这里您可以覆盖Collection._removeReference使方法的更适当的清洁。

我不喜欢的原因有两个解决方案,此:

  • 我不喜欢覆盖已有调用一个方法super后。
  • 我不喜欢覆盖私有方法

2.过度包装您的Collection.reset()调用

至极是相反的:代替添加更深的功能中,添加上功能

然后,而不是调用Collection.reset()直接就可以调用清理模型之前已经悄悄删除的实现:

cleanUp: function( data ){
  this.each( function( model ) { model.unlink(); } );
  this.reset( data );
} 

你的代码可以的分拣机版本是这样的:

AppEvents = {};
_.extend(AppEvents, Backbone.Events)

var User = Backbone.Model.extend({
  initialize: function(){
    AppEvents.on('my_event', this.listen, this);
  },

  listen: function(){
    console.log("%s still listening...", this.get('name'));
  },

  unlink: function(){
   AppEvents.off( null, null, this );
  }
});

var Users = Backbone.Collection.extend({
  model: User,

  cleanUp: function( data ){
    this.each( function( model ) { model.unlink(); } );
    this.reset( data );
  }
});


// testing
var users = new Users([{name: 'John'}]);
console.log('users.size: ', users.size()); // 1
AppEvents.trigger('my_event');             // John still listening...

users.cleanUp();
console.log('users.size: ', users.size()); // 0
AppEvents.trigger('my_event');             // (nothing)

检查中的jsfiddle 。

更新:验证,该模型后取出取消绑定事件链接

我们验证Object1听在Object2的事件的第一件事会在方向Obect2链接- > Object1:

在上面的图像,我们看到作为模型(@ 314019)不仅由所保持的users集合,但也为AppEvents对象,它是观察。 看起来像连接一个程序员的角度的情况,听对象- >到- >正在听的对象 ,但实际上是完全相反的: 就是听了对象- >到- >对象,它是听

现在,如果我们使用Collection.reset()清空我们所看到的是集合users链接已被删除,但AppEvents链接仍然是:

users链接已经消失,并且还链接OurModel.collection什么,我认为是的一部分Collection._removeReference()的工作。

当我们用我们的Collection.cleanUp()方法的对象从内存中消失,我不能让Chrome.profile工具来明确地告诉我对象@ 314019已被删除 ,但我可以看到, 它已不再内存中对象



Answer 2:

我认为干净引用过程是一个棘手的部分Backbone

当您删除ModelCollection集合细心地unbind在该集合自身是有约束力的模型的任何事件。 检查这个私人收藏方法 。

也许你可以在你的聚合使用这种相同的技术:

// ... Aggregator code
the_model.on( "remove", this.unlinkModel, this );
// ... more Aggregator code

unlinkModel: function( model ){
  model.off( null, null, this );
}

这是的情况下的结合的方向是聚集- >模型 。 如果方向是相反的,我不认为你必须作出任何清洁模式删除后。



Answer 3:

相反,包装的CollectionresetcleanUp作为fguillen建议,我宁愿延长Collection并覆盖reset直接。 其原因是, cleanUp生效只有在客户端的代码,而不是在库(即主干 )的。 例如, Collection.fetch可以内部调用Collection.reset 。 除非修改骨干的源代码,我们不能解除绑定模型从事件(如cleanUp调用后) Collection.fetch

基本上,我建议的片段如下:

var MyCollection = Backbone.Collection.extend({
        reset: function(models, options) {
            this.each(function(model) {
                model.unlink(); // same as fguillen's code
            });
            Backbone.Collection.prototype.reset.apply(this, arguments);
        }
    });

后来,我们可以创建基于集合的新MyCollection



文章来源: Backbone.js: how to unbind from events, on model remove