at the time of project development, the scope of global scope and Directive local scope is not clear enough, global scope and Directive local scope communication is not well grasped, here is the global scope and Directive the use of local scope to make a summary.
I. Scope scope
1. In Angularjs, child scopes generally inherit the properties and methods of their parent scopes through the JavaScript prototype inheritance mechanism. There is one exception: using scope in directive: {...}, the scope created in this way is a separate "isolate" scope, it also has a parent scope, but the parent scope is not on its prototype chain and does not inherit from the parent scope. This approach defines a scope that is typically used to construct reusable directive components.
2, if we access a property defined in a parent scope in a child scope, JavaScript first looks for the attribute in the child scope, finds it again from the parent scope on the prototype chain, and finds the parent scope of the previous prototype chain if it is not found. In Angularjs, the top of the scope prototype chain is $rootscope,javascript to find $rootscope.
3. Scope: {...}-directive creates a separate "isolate" scope with no prototype inheritance. This is the best choice for creating reusable directive components. Because it does not directly access/modify the properties of the parent scope, it does not produce unexpected side effects.
II, isolate scope reference modifier
1, = or =attr" Isolate " The properties of the scope are bound to the properties of the parent scope, and the modification of either party affects the other, which is the most common way; the properties of the
2, @ or @attr "isolate" are one-way bound to the properties of the parent scope, that is, "isolate" The scope can only read the value of the parent scope, and the value is always of type string; the
3, & or &attr "isolate" scope wraps the properties of the parent scope into a function to read and write the properties of the parent scope in a functional way. The wrapping method is $parse
iii. directive and controller data transmission and communication
1. The parent controller listens to global scope (parent scope) variables and broadcasts events to the child scope (Directive scope, each Directvie has its own scope scope)
2. Directive defines local scope and refers to global scope by =, @, & (method) characters
3. Directive scope (sub scope) refers to global scope properties by parent[$scope. $parent. xxx]
4, Directive listening to global scope variable changes, can pass $scope. $parent. $watch method
Iv. Illustration of the case
<div ng-controller="MyCtrl">
<button ng-click="show=true">show</button>
<dialog title="Hello }"
Visible="}"
On-cancel="show=false;"
On-ok="show=false;parentScope();">
<!--The above on-cancel, on-ok, is passed & referenced in the isoloate scope of the directive.
If the expression contains a function, you need to bind the function to the parent scope (currently the scope of MyCtrl) -->
Body goes here: username:} , title:}.
<ul>
<!--This can also be played here~names is the parent scope-->
<li ng-repeat="name in names">}</li>
</ul>
<div>
Email:<input type="text" ng-model="email" style="width: 200px;height:20px"/>
</div>
<div>
Count:<input type="text" ng-model="person.Count" style="width: 120px;height:20px"/>
<button ng-click="changeCount()">Count plus 1</button>
</div>
<p></p>
</dialog>
</div>
C ontroller test code:
Var app = angular.module("Dialog", []);
App.controller("MyCtrl", function ($scope) {
$scope.person = {
Count: 0
};
$scope.email = 'carl@126.com';
$scope.names = ["name1", "name2", "name3"];
$scope.show = false;
$scope.username = "carl";
$scope.title = "parent title";
$scope.parentScope = function () {
Alert ("scope inside through & defined stuff, is defined in the parent scope");
};
$scope.changeCount = function () {
$scope.person.Count = $scope.person.Count + 1;
}
/ / Monitor the controller count changes, and issue an event broadcast, then listen to the count CountStatusChange change event in the directive
$scope.$watch('person.Count', function (newVal, oldVal) {
Console.log('>>>parent Count change:' + $scope.person.Count);
If (newVal != oldVal) {
Console.log('>>>parent $broadcast count change');
$scope.$broadcast('CountStatusChange', {"val": newVal})
}
});
});
App.directive('dialog', function factory() {
Return {
Priority: 100,
Template: ['<div ng-show="visible">',
' <h3>}</h3>',
' <div class="body" ng-transclude></div>',
' <div class="footer">',
' <button ng-click="onOk()">OK</button>',
' <button ng-click="onCancel()">Close</button>',
' </div>',
'</div>'].join(""),
Replace: false,
Transclude: true,
Restrict: 'E',
Scope: {
Title: "@", / / reference the value of the title tag attribute of the dialog tag
Visible: "@", / / reference the value of the visible tag visible attribute
onOk: "&", / / reference the contents of the on-ok attribute of the dialog tag in the form of a wrapper function
onCancel: "&"//refers to the contents of the on-cancel attribute of the dialog tag as a wrapper function
},
Controller: ['$scope', '$attrs', function ($scope, $attrs) {
// directive scope title quotes the value of the title attribute of the dialog tag via @, so the value can be retrieved here.
Console.log('>>>title:' + $scope.title);
>>>title:Hello carl scope.html:85
/ / Get the parent scope variable page directly through $parent
Console.log('>>>parent username:' + $scope.$parent.username);
>>>parent username:carl
// directive scope does not define the username variable, and does not reference the parent scope username variable, so here is undefined
Console.log('>>>child username:' + $scope.username);
>>>username:undefined
/ / Receive the count change event broadcast by the parent controller
$scope.$on('CountStatusChange', function (event, args) {
Console.log("child scope on(listening) recieve count Change event :" + args.val);
});
// watch parent controller scope object
$scope.$parent.$watch('person.Count', function (newVal, oldVal) {
Console.log('>>>>>>>child watch parent scope[Count]:' + oldVal + ' newVal:' + newVal);
});
}]
};
});