本文介绍了不Backbone.Models this.get()整个数组或点复制到内存中的同一阵列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  =人Backbone.Model.extend({
        默认值:{
            名称:'胎儿',
            年龄:0,
            孩子:[]
        },
        初始化:功能(){
            警报(欢迎来到这个世界上);
        },
        采纳:功能(newChildsName){
            VAR children_array = this.get(孩子);
            children_array.push(newChildsName);
            this.set({孩子:children_array});
        }
    });    变种人=新的Person({名:托马斯,年龄:67,儿童:['瑞恩']});
    person.adopt(约翰Resig的');
    VAR孩子= person.get(孩子); // ['瑞恩','约翰Resig的']

在这个例子中code,我们有:

children_array = this.get(孩子)

我想这将只是指向同一阵列中的内存(因此是O(1))。不过转念一想,这将是一个地板的设计,因为一个可以操纵的阵列,而无需使用this.set(),然后事件侦听器就不会开火。

所以我猜它(不知何故神奇地)复制阵列??

该怎么办?

编辑:我刚刚发现在骨干源$ C ​​$ C实施https://github.com/documentcloud/backbone/blob/master/backbone.js (我已经贴在底部相关code)

获取回报:

 收益this.attributes [ATTR]

所以这将只是指向内存权的同一阵列?因此,人们可能会改变,而无需使用集(阵列),这将是坏..?我是正确的?

 得到:函数(ATTR){
      返回this.attributes [ATTR]
    },    //获取属性的HTML转义值。
    逃跑:功能(ATTR){
      VAR HTML;
      如果(HTML = this._escapedAttributes [ATTR])返回HTML;
      VAR VAL = this.get(attr)使用;
      返回this._escapedAttributes [ATTR = _.escape(VAL == NULL''''+ VAL);
    },    //如果属性包含的值不为空返回TRUE
    //或不确定。
    有:函数(ATTR){
      返回this.get(attr)使用!= NULL;
    },    //设置模型的属性散列的对象,射击`变除非`
    //你选择沉默吧。
    设置:功能(键,值,选项){
      VAR ATTRS,ATTR,VAL;      //同时处理`钥匙,value`和`{键:值}`式的论点。
      如果(_.isObject(密钥)||键== NULL){
        ATTRS =键;
        选项​​=价值;
      }其他{
        的attrs = {};
        ATTRS [关键] =价值;
      }      //提取属性和选项。
      选择|| (选项= {});
      如果返回此(ATTRS!);
      如果(ATTRS的instanceof模型)ATTRS = attrs.attributes;
      如果(options.unset)为(以ATTRS attr)使用ATTRS [ATTR] = 0无效;      //运行验证。
      (!this._validate(ATTRS,期权))如果返回false;      //检查id`的`变化。
      如果(this.idAttribute在ATTRS)this.id = ATTRS [this.idAttribute]      VAR变化= options.changes = {};
      VAR现在= this.attributes;
      VAR逃脱= this._escapedAttributes;
      VAR preV =该._ previousAttributes || {};      //对于每一个`set`属性...
      对(在ATTRS ATTR){
        VAL = ATTRS [ATTR]        //如果新的和当前的值不同,记录更改。
        如果(的isEqual _(现[ATTR],VAL)||(options.unset&安培;!&放大器; _.has(现,ATTR))){
          删除逃脱[ATTR]
          (options.silent this._silent:改变?)[ATTR] =真;
        }        //更新或删除当前值。
        options.unset?现在可以删除[ATTR]:现在[ATTR = VAL;        //如果新和previous值不同,记录更改。如果不,
        //然后删除该属性的变化。
        如果(!_。isEqual:方法(preV [ATTR],VAL)||(_.has(现,attr)使用!== _.has(preV,ATTR))){
          this.changed [ATTR = VAL;
          如果(options.silent!)this._pending [ATTR] =真;
        }其他{
          删除this.changed [ATTR]
          删除this._pending [ATTR]
        }
      }      //火`变`事件。
      如果(options.silent!)this.change(选件);
      返回此;
    },


解决方案

的文档接口实际上并不指定谁拥有数组引用,所以你是你自己在这里。如果你看一下实现,你会看到(像你一样)的 GET 刚刚返回直出的型号的内部属性。这能与不变类型(如数字,字符串和布尔值),但运行到与可变类型的问题,如数组:你可以很容易地改变一些事情,而不必骨干知道关于它的任何方式

骨干机型似乎意在牵制基本类型。

有三个原因叫设置


  1. 这就是接口规范说的事情。

  2. 如果你不叫设置,你不触发事件。

  3. 如果你不叫设置,你会绕过验证逻辑设置了。

您只需要当你使用数组和对象值的工作要小心。

请注意,这种行为 GET 设置是一个实现细节和未来的版本中可能会得到关于如何聪明,他们处理非原始属性值。


与阵列的情况属性(为此事对象属性)实际上是比你差可能最初怀疑。当你说 m.set(P,V),骨干会不会考虑设置是一个变化,如果 v === current_value_of_p ,所以如果你拉出来一个数组:

  VAR一个= m.get(P);

然后修改它:

  a.push(X);

和发回的:

  m.set(P,A);

您不会从模型中获取一个改变事件,因为 A === A ; 使用下划线的的与!== 但效果是在这种情况下是相同的。

例如,诈骗的这个简单的一点:

  VAR M = Backbone.Model.extend({});
变种M =新的M({号码:[1]});
m.on('变',函数(){的console.log('改为')});的console.log('设置新的数组');
m.set('P',[2]);的console.log('更改,恕不集');
。m.get('P')推(3);的console.log('GET数组,变更,并重新设置');
VAR一个= m.get('P'); a.push(4); m.set('P',一);的console.log('GET数组,克隆它,改变它,将它设置');
A = _(m.get('P'))的clone()。 a.push(5); m.set('P',一);

产生两个改变事件:一前一后第一个设置和一个最后<$ C $之后C>设置。

演示:

如果你看看设置你会发现,有对属性的一些特殊的处理是 Backbone.Model 秒。


这里的基本教训很简单:

这篇关于不Backbone.Models this.get()整个数组或点复制到内存中的同一阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 18:36