【问题标题】:Backbone view-property: one on instance, one on prototype?主干视图属性:一个在实例上,一个在原型上?
【发布时间】:2013-07-02 12:11:03
【问题描述】:

是的,这个标题没有多大意义。

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

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 次。什么是主干?

【问题讨论】:

    标签: javascript inheritance backbone.js prototype


    【解决方案1】:

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

    所以,这就是这里发生的事情:

    当您将contactViewItems 修改为this.contactViewItems.push(view); 时,您不会更改原型中存储的值。相反,您更改了该值所指向的对象。因此,您仍在修改一个由您的类的所有实例共享的数组。

    但是,当您执行this.contactViewItems = []; 时,您实际上是在更改值,因为您正在给它一个全新的对象。那时,您只需遮蔽您的类的原型,特别是针对该实例。原型当然仍然存在(您没有对其进行任何操作),因此您会看到该属性两次。

    现在,它肯定没有按您希望的那样工作,并且我相信您现在可以想到几种解决方案,因为您知道问题的核心(我不知道您的应用程序的详细信息,所以如果没有更多详细信息,我就帮不上什么忙了)。

    【讨论】:

      【解决方案2】:

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

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

      this.contactViewItems = [];
      

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

      MN.ContactsView.prototype.contactViewItems = [];
      

      this.contactViewItems.length = 0;
      

      【讨论】:

        【解决方案3】:

        正如 Loamhoof 所指出的,问题在于您的contactViewItems 是您的ContactsViews 原型的属性。

        修改视图使其行为符合您预期的一种简单方法是不要使用空数组初始化contactViewItems。相反,在您的初始化中创建空数组。

        例如:

        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。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-11-15
          • 2015-07-23
          • 2011-07-04
          • 2012-01-31
          • 1970-01-01
          • 2011-12-12
          • 1970-01-01
          相关资源
          最近更新 更多