javascript – Backbone.js:如何取消绑定事件,模型删除

在骨干网中,我们有一个应用程序,它使用位于window.App.Events上的事件聚合器
现在,在许多视图中,我们绑定到该聚合器,并且我在视图上手动编写了一个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始终处于适当位置,以便于在整个应用程序中传递事件.

代码示例显示,即使从集合中删除它们,它们也不再存在于房屋中,但是当窃贼进入房屋时仍然执行hide命令.

解决方法

我看到即使绑定事件方向是这样的方式Object1 – >听 – >必须删除Object2才能使Object1丢失任何活动引用.

并且看到听模型删除事件不是解决方案,因为它没有在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对象已被删除,但我可以看到它已不再存在于内存中对象.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


什么是深拷贝与浅拷贝?深拷贝与浅拷贝是js中处理对象或数据复制操作的两种方式。‌在聊深浅拷贝之前咱得了解一下js中的两种数据类型:
前言 今天复习了一些前端算法题,写到一两道比较有意思的题:重建二叉树、反向输出链表每个节点 题目 重建二叉树: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列 {1,2,4,7,3,5,6,8} 和中序遍历序列 {
最近在看回JavaScript的面试题,this 指向问题是入坑前端必须了解的知识点,现在迎来了ES6+的时代,因为箭头函数的出现,所以感觉有必要对 this 问题梳理一下,所以刚好总结一下JavaScript中this指向的问题。
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高
JS对象如何转为json格式字符串
JS怎么获取图片原始宽高
怎么在click事件中调用多个js函数
js如何往数组中添加新元素
js如何拆分字符串
JS怎么对数组内元素进行求和
JS如何判断屏幕大小
js怎么解析json数据
js如何实时获取浏览器窗口大小
原生JS实现别踩白块小游戏(五)