0

We can inherit a scope (or I may think of it as the usual outer scope / inner scope scenario):

Same controller: https://jsfiddle.net/fk4hzvxw/

Different controllers: https://jsfiddle.net/fk4hzvxw/1/

<div ng-app="myApp">

  <div ng-controller="hihi">
    <div ng-init="ha = 42"></div>
    <input type="text" ng-model="ha"> {{ ha }}

    <div ng-controller="hello">
      <input type="text" ng-model="ha"> {{ ha }}
    </div>
  </div>

</div>

So I think, it is said that, controller "hihi" creates a scope, and controller "hello" creates also a scope, and inherits the scope created by controller "hihi". (Or I might think of it as just outer scope and inner scope like in a traditional program -- is this a correct way to think about it?)

We can type into the first input box, and all values on the screen update to the same value. However, when we type into the second input box, then the second variable seems to "take off as its own". Now there are 2 variables ha, one in the outer scope, one in the inner scope, as we type into the 2 input box, they affect only its own scope's variable.

How should we think about this? In traditional programming, this won't happen. Also, what are the implications of this?

nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • 1
    would highly recommend to read up on article [how prototypal inheritance work in angularjs](http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs) – Pankaj Parkar Feb 20 '16 at 12:07

2 Answers2

1

This can happen in traditional programming. Think of the scopes as a series of Javascript objects where each object has the parent scope as its prototype. Whenever you access an attribute of an object the prototype chain is searched until a match is found, but assigning to an attribute simply assigns it on the object itself.

In other languages you might see something similar, e.g. in Python accessing an attribute on a class searches all the parent classes but assigning it on an object hides all the parent values.

The way to avoid this in Angular is to always use the 'controller as' syntax. This gives every controller a name and you can then be sure which one will have its model updated.

<div ng-app="myApp">

  <div ng-controller="hihi as hihi">
    <div ng-init="ha = 42"></div>
    <input type="text" ng-model="hihi.ha"> {{ hihi.ha }}

    <div ng-controller="hello as hello">
      <input type="text" ng-model="hello.ha"> {{ hello.ha }}
    </div>
  </div>

</div>

But then inside the controller code you access the attributes through this instead of using $scope (and there's also a convention that you do var vm=this; at the top of the controller and use vm to avoid problems with this varying in nested functions).

Duncan
  • 92,073
  • 11
  • 122
  • 156
  • so when we think about `$scope`, it is better to think about an object (and its properties), instead of a "scope" in traditional programming? – nonopolarity Feb 20 '16 at 12:07
0

(Or I might think of it as just outer scope and inner scope like in a traditional program -- is this a correct way to think about it?)

Yup. This has more to do with how JavaScript works(the scope chain) than with AngularJS.

When the JavaScript interpreter comes across a variable, it searches for it in the current scope. If it doesn't find it, it moves to the outer scope of the current scope and keeps on going up the scope chain until the variable is found.

You can read up on the JavaScript scope chain here.

Tarun Dugar
  • 8,921
  • 8
  • 42
  • 79