现在,在许多视图中,我们绑定到该聚合器,并且我在视图上手动编写了一个destroy函数,该函数处理来自该事件聚合器的解绑定,然后删除视图. (而不是直接删除视图).
现在,某些模型我们也需要这个功能,但我无法弄清楚如何解决它.
某些模型需要绑定到某些事件,但也许我错了,但是如果我们从集合中删除模型,它会保留在内存中,因为这些绑定到事件聚合器仍然存在.
模型上没有真正的删除功能,就像视图一样.
那我怎么解决这个问题呢?
编辑
根据要求,一些代码示例.
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: ','burglar2'); });
在jsFiddle上查看此代码(在控制台中输出):http://jsfiddle.net/saelfaer/szvFY/1/
正如您所看到的,我不会绑定模型上的事件,而是绑定到事件聚合器.
来自模型本身的解除绑定事件是没有必要的,因为如果它被移除,没有人会再次触发它上面的事件.但eventAggregator始终处于适当位置,以便于在整个应用程序中传递事件.
解决方法
并且看到听模型删除事件不是解决方案,因为它没有在Collection.reset()调用中调用,那么我们有两个解决方案:
1.覆盖正常的Collection cleanUp
作为@dira sais here,您可以覆盖Collection._removeReference以更正确地清除方法.
我不喜欢这个解决方案有两个原因:
>我不喜欢覆盖一个必须在它之后调用super的方法.
>我不喜欢覆盖私有方法
2.重新包装Collection.reset()调用
然后,不是直接调用Collection.reset(),而是可以在静默删除之前调用cleanUp模型的实现:
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)
检查the jsFiddle.
首先我们验证Object1在Object2中监听事件会在Obect2 – >方向创建一个链接. Object1:
在上面的图像中,我们看到模型(@ 314019)不仅由用户集合保留,而且还为正在观察的AppEvents对象保留.看起来像程序员透视链接的事件是侦听的对象 – >到 – >被监听但实际上完全相反的对象:被监听的对象 – >到 – >正在倾听的对象.
现在,如果我们使用Collection.reset()来清空Collection,我们看到已删除了用户链接,但AppEvents链接仍然存在:
用户链接已经消失,链接OurModel.collection我认为是Collection._removeReference()作业的一部分.
当我们使用Collection.cleanUp()方法时,对象从内存中消失,我无法让Chrome.profile工具明确地告诉我@ 314019对象已被删除,但我可以看到它已不再存在于内存中对象.