Angular中的范围继承

时间:2014-01-01 16:26:25

标签: javascript angularjs angularjs-scope

我是Angular的新手,所以我正在尝试按照教程进行操作,但是没有得到它。让我感到困惑的是点符号:

<div ng-app="">
  <input type="text" ng-model="data.message">
  <h1>{{ data.message }}</h1>

  <div ng-controller="FirstCtrl">
    <input type="text" ng-model="data.message">
    <h1>{{ data.message }}</h1>
  </div>

  <div ng-controller="SecondCtrl">
    <input type="text" ng-model="data.message">
    <h1>{{ data.message }}</h1>
  </div>
</div>

在任何输入框内键入值将更新所有其他输入框。 所以,我认为这里发生的是控制器外部的第一个ng-model声明是将输入元素值绑定到根作用域中的data.message模型。我不明白如何绑定{{{1}然后1}}从根范围读取值,以及为什么在ng-controller范围内插入的值将显示在该范围之外的输入框中?

如果ng-controller被移除

data.

这种行为已经消失,怎么回事?

2 个答案:

答案 0 :(得分:4)

你的第一个例子是在Angular中做事的推荐方法。最佳做法是ngModel中应该始终有一个点,因为在ngModel中使用基元是Angular中常见的错误来源。

这在Angular's understand scopes document中详细讨论:

  

通过遵循以下内容,可以轻松避免使用原语这个问题   always have a '.' in your ng-models的“最佳实践” - 观察3   分钟值得。 Misko演示了原始绑定问题   NG-开关。

但简而言之,这是由于Javascript的原型继承如何运作。

在你的第二个例子中,每个ngModel内都有一个基本类型 - 例如一个字符串。当每个控制器中的ngModel(每个控制器都在他们自己的子范围内)尝试从原始类型读取时,他们首先查看他们的父母,看看该变量是否存在。如果是,那么他们就从中读取。但是,当其中一个ngModels 写入到该原语时,则会在其范围上添加该原语的新实例。

因此,每个input首先共享一个公共变量(顶部作用域上的变量),当只读取时,然后每个input在写入后切换到使用自变量。您可以首先在顶部输入父级input,然后在子级中输入in this fiddle来查看此操作。

Angular建议避免这种情况,因为阅读和书写操作之间的不匹配显然会非常容易混淆和容易出错

在您的第一个示例中,您改为使用属性data创建对象message。在这种情况下,读取就像使用原语一样 - 它看起来在父作用域上找到具有该属性的对象,并且如果它在那里则从中读取。但这次写作的工作方式与阅读相同 - 如果存在具有属性data的父对象message,则写入对象的属性。

所以,当你使用点符号时,读写行为一致,你可以看到in this fiddle

答案 1 :(得分:1)

在第一个代码中,data作为对象是三个范围之间的公共对象,每个范围都引用数据。因此,当data.message更改时,所有三个范围都显示已更改的消息。 但在第二种情况下,message是一个字符串,它是一个值类型而不是一个对象。每个范围都有自己的消息,更改主题之一不会影响其他范围。