javascript tutorial - [Solved-5 Solutions] Nuances of scope prototypal / prototypical inheritance in AngularJS - javascript - java script - javascript array
Problem:
What are the nuances of scope prototypal / prototypical inheritance in AngularJS ?
Solution 1:
A child scope normally prototypically inherits from its parent scope, but not always. One exception to this rule is a directive with scope: { ... } -- this creates an "isolate" scope that does not prototypically inherit. This construct is often used when creating a "reusable component" directive.
As for the nuances, scope inheritance is normally straightfoward... until you need 2-way data binding (i.e., form elements, ng-model) in the child scope. Ng-repeat, ng-switch, and ng-include can trip you up if you try to bind to a primitive (e.g., number, string, boolean) in the parent scope from inside the child scope. It doesn't work the way most people expect it should work. The child scope gets its own property that hides/shadows the parent property of the same name. Your workarounds are
- define objects in the parent for your model, then reference a property of that object in the child: parentObj.someProp
- use $parent.parentScopeProperty (not always possible, but easier than 1. where possible)
- define a function on the parent scope, and call it from the child (not always possible)
New AngularJS developers often do not realize that ng-repeat, ng-switch, ng-view, ng-include and ng-if all create new child scopes, so the problem often shows up when these directives are involved. Having a '.' in your models will ensure that prototypal inheritance is in play. So, use
<input type="text" ng-model="someObj.prop1">
<!--rather than
<input type="text" ng-model="prop1">`
-->
click below button to copy the code. By JavaScript tutorial team
Solution 2:
childScope.aString === 'parent string'
childScope.anArray[1] === 20
childScope.anObject.property1 === 'parent prop1'
childScope.aFunction() === 'parent output'
click below button to copy the code. By JavaScript tutorial team
Solution 3:
Suppose we have in our controller:
$scope.myPrimitive = 50;
$scope.myObject = {aNumber: 11};
click below button to copy the code. By JavaScript tutorial team
And in our HTML:
<script type="text/ng-template" id="/tpl1.html">
<input ng-model="myPrimitive">
</script>
<div ng-include src="'/tpl1.html'"></div>
<script type="text/ng-template" id="/tpl2.html">
<input ng-model="myObject.aNumber">
</script>
<div ng-include src="'/tpl2.html'"></div>
click below button to copy the code. By JavaScript tutorial team
Solution 4:
First we create "Parent" object function
function Parent(){
}
click below button to copy the code. By JavaScript tutorial team
Then add a prototype to "Parent" object function
Parent.prototype = {
primitive : 1,
object : {
one : 1
}
}
click below button to copy the code. By JavaScript tutorial team
Create "Child" object function
function Child(){
}
click below button to copy the code. By JavaScript tutorial team
Assign child prototype (Make child prototype inherit from parent prototype)
Child.prototype = Object.create(Parent.prototype);
click below button to copy the code. By JavaScript tutorial team
Assign proper "Child" prototype constructor
Child.prototype.constructor = Child;
click below button to copy the code. By JavaScript tutorial team
Add method "changeProps" to a child prototype, which will rewrite "primitive" property value in Child object and change "object.one" value both in Child and Parent objects
Child.prototype.changeProps = function(){
this.primitive = 2;
this.object.one = 2;
};
click below button to copy the code. By JavaScript tutorial team
Initiate Parent (dad) and Child (son) objects.
var dad = new Parent();
var son = new Child();
click below button to copy the code. By JavaScript tutorial team
Call Child (son) changeProps method
son.changeProps();
click below button to copy the code. By JavaScript tutorial team
- Check the results.
- Parent primitive property did not change
console.log(dad.primitive); /* 1 */
click below button to copy the code. By JavaScript tutorial team
Child primitive property changed (rewritten)
console.log(son.primitive); /* 2 */
click below button to copy the code. By JavaScript tutorial team
Parent and Child object.one properties changed
console.log(dad.object.one); /* 2 */
console.log(son.object.one); /* 2 */
click below button to copy the code. By JavaScript tutorial team
Solution 5:
myObject.prop = '123';
click below button to copy the code. By JavaScript tutorial team
It doesn't look up the chain, but when you set
myObject.myThing.prop = '123';