0

This example is from ng-book: The complete book on AngularJS. I don't understand the result of the following example.

<div ng-controller="SomeController">
    {{ someBareValue }}
    <button ng-click="someAction()">Communicate to child</button>
    <div ng-controller="ChildController">
        {{ someBareValue }}
        <button ng-click="childAction()">Communicate to parent</button>
    </div>
</div>

angular.module('myApp', [])
    .controller('SomeController', function($scope) {
        // anti-pattern, bare value
        $scope.someBareValue = 'hello computer';
        // set actions on $scope itself, this is okay
        $scope.someAction = function() {
            // sets {{ someBareValue }} inside SomeController and ChildController
            $scope.someBareValue = 'hello human, from parent';
        };
    })
    .controller('ChildController', function($scope) {
        $scope.childAction = function() {
        // sets {{ someBareValue }} inside ChildController
        $scope.someBareValue = 'hello human, from child';
    };
});

Example is here: http://output.jsbin.com/UbIRIHa/1/

In the book, it says

Because of the way prototypal inheritance works with value objects in JavaScript, changing someBareValue via an action in the parent does change it in the child, but not vice versa. To see this problem in action, try clicking on the child button first and then the parent button. Doing so makes it clear that the child controller has copy, not a reference to someBareValue.

What I don't understand is that: If, like the book suggests, click on "Communicate to parent" first and click on "Communicate to child", then the "Communicate to child" can't change the text in child.

However, if click on parent button first, it could change the child text then.

I don't understand why the clicking order matters the result of parent button, what role the prototypal inheritance plays in this example?

user1888955
  • 626
  • 1
  • 9
  • 27
  • I think calling this inheritance is pretty much bull. It is variable shadowing, If there is no child variable set then it'll show the parent value. It may mimic some inheritance but it's the same as shadowing a variable from a outer scope just like in any other javascript function. It's just diffused by the fact that the html-template dictates how the scopes are nested. – ippi Jun 12 '18 at 05:14

1 Answers1

0

You can think of a prototype as a set of "default values" for the childScopes that inherit that prototype. Any changes to the prototype will be reflected in the childScopes, but as soon as you assign a specific value to one of those properties on the childScope, the childScope will retain that property thereafter.

Observe:

var parentScope = { message: 'hello' };

var childScope1 = Object.create(parentScope);
var childScope2 = Object.create(parentScope);

console.log(childScope1.message);  // hello
console.log(childScope2.message);  // hello

parentScope.message = "goodbye";

console.log(childScope1.message);  // goodbye
console.log(childScope2.message);  // goodbye

childScope1.message = "I'm different!";

console.log(childScope1.message);  // I'm different!
console.log(childScope2.message);  // goodbye

parentScope.message = "hello again";

console.log(childScope1.message);  // I'm different!
console.log(childScope2.message);  // hello again
JLRishe
  • 99,490
  • 19
  • 131
  • 169