Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
318 views
in Technique[技术] by (71.8m points)

javascript - Scope inheritance in Angular

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...