gpt4 book ai didi

javascript - Backbone.js:如何在模型删除时解除事件绑定(bind)

转载 作者:数据小太阳 更新时间:2023-10-29 04:29:14 24 4
gpt4 key购买 nike

在 backbone 中,我们有一个使用事件聚合器的应用程序,位于 window.App.Events现在,在许多 View 中,我们绑定(bind)到那个聚合器,我在 View 上手动编写了一个 destroy 函数,它处理从那个事件聚合器解除绑定(bind),然后删除 View 。 (而不是直接删除 View )。

现在,有些模型我们也需要此功能,但我不知道如何解决它。

某些模型需要绑定(bind)到某些事件,但也许我错了,但如果我们从集合中删除一个模型,它会保留在内存中,因为这些与事件聚合器的绑定(bind)仍然存在。

模型上并没有真正的删除功能,就像 View 一样。那我该如何解决呢?

编辑根据要求,一些代码示例。

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/

如您所见,我没有绑定(bind)到模型上的事件,而是绑定(bind)到事件聚合器。从模型本身解除绑定(bind)事件,是没有必要的,因为如果它被删除,没有人会再次触发它的事件。但 eventAggregator 始终存在,以便于在整个应用程序中传递事件。

代码示例表明,即使将它们从集合中移除,它们也不再住在房子里,但仍然会在窃贼进入房子时执行隐藏命令。

最佳答案

我看到即使绑定(bind)事件方向是这种方式,Object1 -> listening -> Object2 也必须将其删除,以便 Object1 丢失任何事件引用。

并且看到监听模型 remove 事件不是解决方案,因为它没有在 Collection.reset() 调用中调用,那么我们有两个解决方案:

1。覆盖正常的集合清理

作为@dira sais here您可以覆盖 Collection._removeReference 以更正确地清理该方法。

我不喜欢这个解决方案有两个原因:

  • 我不喜欢覆盖必须在其后调用 super 的方法。
  • 我不喜欢覆盖私有(private)方法

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

恰恰相反:不是添加更深的功能,而是添加更高级的功能

然后您可以调用cleanUp模型的实现,而不是直接调用 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)

检查 the jsFiddle .

更新:删除绑定(bind)事件链接后验证模型是否已删除

首先,我们验证 Object1 监听 Object2 中的事件是否在 Obect2 -> Object1 方向上创建了一个链接:

Our object is retained

在上图中,我们看到模型 (@314019) 不仅由 users 集合保留,而且还用于观察的 AppEvents 对象。从程序员的 Angular 来看,事件链接似乎是 监听的对象 -> 监听的对象 但实际上完全相反:监听的对象listened -> to -> 正在监听的对象

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

Our object is retained 2

users 链接已经消失,还有链接 OurModel.collection 我认为是 Collection._removeReference() 作业的一部分。

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

关于javascript - Backbone.js:如何在模型删除时解除事件绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10429648/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com