Backbone view-property:一个在实例上,一个在原型上?

时间:2013-07-02 12:11:04

标签: javascript inheritance backbone.js prototype

是的,这个头衔没有多大意义。

我有一个观点。此视图创建子视图。这些子视图存储在一个数组中,以便我可以在某个时候删除它们。

MN.ContactsView = MN.BaseView.extend ({

tagName : "div",

contactViewItems : [],

initialize : function(){        
    this.listenTo(MN.client.contacts, "add", this.addOne);
    this.listenTo(MN.client.contacts, "reset", this.addAll);
    this.listenTo(MN.client.contacts, "all", this.render);      
    MN.client.contacts.fetch();

},  render: function(){

},

addOne : function($contactModel){       
    var view = new MN.ContactsViewItem({model: $contactModel});
    this.contactViewItems.push(view);
    $("#contactsContainer").append(view.render().el);

},

addAll : function(){
    MN.client.contacts.each(this.addOne, this)
},

close : function(){

},

destroy: function(){
    for(var i =0; i < this.contactViewItems.length; i++) this.contactViewItems[i].destroy();
    this.contactViewItems = [];
    debugger;
    console.log("Length: " + this.contactViewItems.length );
    MN.BaseView.prototype.destroy.call(this);   
},

当我销毁视图并检查调试器时,我看到相同的变量2次。骨干是什么?

enter awesome image description here, dawg

3 个答案:

答案 0 :(得分:3)

当您使用extend方法创建课程时,您提供的属性将放入原型中。这意味着,它们将由您班级的所有实例共享。如果您碰巧在某些情况下更改了该属性的值,您将阴影原型,以便此属性具有新值,而不再与原型链接。

所以,这里发生了什么:

使用contactViewItems修改this.contactViewItems.push(view);时,不会更改原型中存储的值。而是,您更改值指向的对象。所以你仍在修改一个数组,由你所有类的实例共享。

然而,当你执行this.contactViewItems = [];时,你真正在改变这个值,因为你给它一个全新的对象。在那一刻,您只需阴影特别是此类实例的类的原型。原型当然还在那里(你没有对它做任何事情),因此你会看到该属性两次。

现在,它肯定无法正常运行,而且有一些解决方案,我相信你现在可以想到你知道问题的核心(我不知道你应用的细节) ,如果没有进一步的细节我就无法提供太多帮助。)

答案 1 :(得分:0)

  

当我销毁视图并检查调试器时,我会看到相同的变量2次。

因为您已在destroy函数的实例上第二次创建它:

this.contactViewItems = [];

如果你想清除原型上的数组,你应该使用

MN.ContactsView.prototype.contactViewItems = [];

this.contactViewItems.length = 0;

答案 2 :(得分:0)

正如Loamhoof指出的那样,问题是你的contactViewItems是你的ContactsViews原型的属性。

修改视图以使其行为与您可能期望的方式相同的简单方法是不将contactViewItem用空数组进行iniitilize。而是在初始化中创建空数组。

例如:

MN.ContactsView = MN.BaseView.extend ({

tagName : "div",

contactViewItems : null,

initialize : function(){        
    this.contactViewItems = [];
    this.listenTo(MN.client.contacts, "add", this.addOne);
    this.listenTo(MN.client.contacts, "reset", this.addAll);
    this.listenTo(MN.client.contacts, "all", this.render);      
    MN.client.contacts.fetch();
},  

现在,向this.contactViewItems添加项目直接在视图对象上(在这种情况下你可能想要的),而原型包含一个null的contactViewItems。