1

如果以下任何输入的更改将导致所有输入的更改。据我了解,这是因为数据对象对于所有 3 个范围都是通用的

<div class="content-container" ng-app="">
<input type="text" ng-model="data.message">
<h1>{{data.message}}</h1>
<div ng-controller="FirstController">
    <input type="text" ng-model="data.message">
    <h1>{{data.message}}</h1>
</div>
<div ng-controller="SecondController">
    <input type="text" ng-model="data.message">
    <h1>{{data.message}}</h1>
</div>

但如果每个范围以下都有自己的消息对象:

<div class="content-container" ng-app="">
<input type="text" ng-model="message">
<h1>{{message}}</h1>
<div ng-controller="FirstController">
    <input type="text" ng-model="message">
    <h1>{{message}}</h1>
</div>
<div ng-controller="SecondController">
    <input type="text" ng-model="message">
    <h1>{{message}}</h1>
</div>

我不清楚,为什么角度为每个范围创建“消息”对象但不为每个范围创建“数据”对象?这两个示例之间的主要区别是什么?

4

1 回答 1

2

这与 AngularJS 的工作方式无关——实际上,它与 JavaScript 的工作方式有关。考虑以下:

function Parent() { 
  this.message = ''; 
  this.data    = {};
}
function Child() {}; Child.prototype = new Parent();

如您所见,Parent当用作构造函数时,它为新对象定义了两个属性。假设我们将使用第一个存储原语,使用第二个存储对象。

Child函数的定义非常简单:没有自己的属性,Parent在其原型链中有对象。现在对他们做更多的事情:

var c = new Child();
c.message      = '42';
c.data.message = '42';
console.log(c.hasOwnProperty('message'));         // true
console.log(c.hasOwnProperty('data'));            // false
console.log(c.data.hasOwnProperty('message'));    // true

看到不同?在第一种情况下,c.message我们在对象 ( c) 本身上定义了一个新属性 - 现在该子对象隐藏了在其原型上定义的同名属性。

然而,在第二种情况下,我们仍然使用parent的属性,用一个新属性扩展它的值。没有定义新的属性c,只有它的原型受到影响;区别在这里更加明显:

var d = new Child();
d.message      = '34';
d.data.message = '34';

console.log(c.message);      // still '42'
console.log(c.data.message); // now '34'

当您使用 Angular 指令时会发生类似的事情:定义了一个新范围,从其父范围继承所有“模型”属性。但除非这些属性是“两级”的,否则分配给它们会在子级上引入同名属性,从而影响为父级定义的属性。

我建议从 Angular wiki 研究Understanding Scopes文档:它对这种行为有更多实质性(并且插图也很丰富!)的解释。然而,这句话很好地总结了它:

通过遵循始终使用“.”的“最佳实践”,可以轻松避免原语的这个问题。在您的 ng 模型中。

对于确实只想使用原语的情况,它提到了一些解决方法:$parent.parentScopeProperty我想这是最直接的一种。

于 2013-09-20T00:33:54.163 回答