Angular 中的作用域继承 [英] Scope inheritance in Angular

查看:25
本文介绍了Angular 中的作用域继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Angular 的新手,所以我正在尝试按照教程进行操作,只是不明白.让我感到困惑的是点符号:

<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 ng-controller="SecondCtrl"><input type="text" ng-model="data.message"><h1>{{ data.message }}</h1>

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

如果 data. 被删除

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

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

这种行为消失了,怎么会?

解决方案

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

Angular 的理解范围文档对此进行了详细讨论:

<块引用>

遵循以下原则可以轻松避免原语的这个问题的最佳实践"总是有一个 '.'在你的 ng-models 中 – 观看 3分钟值.Misko 演示了原始绑定问题ng-switch.

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

在您的第二个示例中,您在每个 ngModel 中有一个原始类型 - 例如一个字符串.当每个控制器中的 ngModel 尝试从原始类型读取时,它们首先查看它们的父类型,看看变量是否存在.如果是,那么他们会从中阅读.但是,当其中一个 ngModels 写入 到该原语时,会在其作用域上添加该原语的新实例.

因此,每个 input 首先共享一个公共变量(位于顶部范围的变量),仅在读取时,然后每个 input 切换到使用独立的一旦写入变量.您可以在 in this fiddle 中通过首先输入 top、parent、input 来观看此操作 然后在孩子中.

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

在你的第一个例子中,你创建了一个对象 data 和一个属性 message.在这种情况下,读取的工作就像使用原始类型一样 - 它看起来在父作用域上找到具有该属性的对象,并在它存在时从中读取.但是这次写入的工作方式与读取的方式相同 - 如果存在具有属性 message 的父对象 data 则写入对象的属性.

因此,当您使用点表示法时,阅读和书写的行为一致,正如您所看到的 在这个小提琴中

I'm new to Angular, so I'm trying to follow tutorial and just don't get it.What confuses me is the dot notation:

<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>

Typing a value inside any of the input boxes will update all the other input boxes. So, what I think that is going on here is that the first ng-model declaration outside controllers is binding the input element value to the data.message model in the root scope.I don't understand how the bindings inside ng-controller are then reading the value from the root scope, and why values inserted inside ng-controller scope will be shown in a input box outside that scope?

Also if data. is removed

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

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

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

that behavior is gone, how come?

解决方案

Your first example is the recommended way to do things in Angular. The best practice being that there should always be a dot in your ngModels as using primitives in an ngModel is a common source of bugs in Angular.

This is discussed at length in Angular's understand scopes document:

This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models – watch 3 minutes worth. Misko demonstrates the primitive binding issue with ng-switch.

But in short this is due to how Javascript's prototypal inheritance works.

In your second example you have a primitive type - a string for example- inside each ngModel. When the ngModel in each controller (each on their own child scopes) tries to read from a primitive type they look to their parents first to see if the variable is there. If it is then they read from it. However when one of the ngModels writes to that primitive then a new instance of the primitive is added on it's scope.

Thus each input shares a common variable (the one on your top scope) at first, when only being read from, and then each input switches to using an independent variable once it's written to. You can watch this in action in this fiddle by first typing in the top, parent, input and then in the children.

Angular recommends avoiding this since the mismatch between how reading and writing operate can clearly be very confusing and error prone

In your first example you're instead creating an object data with a property message. In this case reading works just like with a primitive- it looks to find that object with that property on the parent scope and reads from it if it's there. But this time writing works the same way as reading- if there is a parent object data with property message then the write is done to the object's property.

So, when you use dot notation, reading and writing act consistently as you can see in this fiddle

这篇关于Angular 中的作用域继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆