<!doctype html> <html> <head> <meta charset=utf-8"/> <title>scope nick</title> <script src="https://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script> </head> <script type="text/javascript"> angular.module('app', []) .controller('parentCtrl', ['$scope', function($scope) { $scope.args = {}; $scope.args.content = 'Nick DeveloperWorks'; }]) .controller('childCtrl', ['$scope', function($scope) { }]); </script> <body ng-app="app"> <div ng-controller="parentCtrl"> <input ng-model="args.content"> <div ng-controller="childCtrl"> <input ng-model="args.content"> </div> </div> </body> </html>
测试结果是无论改变任何一个输入框的内容,两者的内容始终同步。
根据 AngularJS 的原型继承机制,如果 ng-model 绑定的是一个对象数据,那么 AngularJS 将不会为 childCtrl 创建一个 args 的对象,自然也不会有 args.content 属性。这样,childCtrl 作用域中将始终不会存在 args.content 属性,只能从父作用域中寻找,也即是两个输入框的的变化其实只是在改变 parentCtrl 作用域中的 args.content 属性。因此,两者的内容始终保持同步。
我们再看一个例子,分析结果如何。
示例四:作用域继承实例-不再访问父作用域的数据对象。
<!doctype html> <html> <head> <meta charset=utf-8"/> <title>scope nick</title> <script src="https://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script> </head> <script type="text/javascript"> angular.module('app', []) .controller('parentCtrl', ['$scope', function($scope) { $scope.args = {}; $scope.args.content = 'Nick DeveloperWorks'; }]) .controller('childCtrl', ['$scope', function($scope) { $scope.args = {}; $scope.args.content = 'Nick DeveloperWorks for test'; }]); </script> <body ng-app="app"> <div ng-controller="parentCtrl"> <input ng-model="args.content"> <div ng-controller="childCtrl"> <input ng-model="args.content"> </div> </div> </body> </html>
测试结果是两个输入框的内容永远不会同步。子作用域有实例数据对象,则不访问父作用域。
独立作用域
独立作用域是 AngularJS 中一个非常特殊的作用域,它只在 directive 中出现。在对 directive 的定义中,我们添加上一个 scope:{} 属性,就为这个 directive 创建出了一个隔离作用域。
示例5: directive 创建出一个孤立作用域
angular.module('isolate', []).directive("isolate", function () { return { scope : {}, }; })
独立作用域最大的特点是不会原型继承其父作用域,对外界的父作用域保持相对的独立。因此,如果在定义了孤立作用域的 AngularJS directive 中想要访问其父作用域的属性,则得到的值为 undefined。代码如下:
示例六:独立作用域的隔离性
<!doctype html> <html> <head> <meta charset=utf-8"/> <title>scope nick</title> <script src="https://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script> </head> <script type="text/javascript"> angular.module('app', []) .controller('ctrl', ['$scope', function($scope) { $scope.args = {}; }]) .directive("isolateDirective", function () { return { scope : {}, link : function($scope, $element, $attr) { console.log($scope.$args); //输出 undefined } }; }); </script> <body ng-app="app"> <div ng-controller="ctrl"> <div isolate-directive></div> </div> </body> </html>
上面的代码中通过在 directive 中声明了 scope 属性从而创建了一个作用域,其父作用域为 ctrl 所属的作用域。但是,这个作用域是孤立的,因此,它访问不到父作用域的中的任何属性。存在这样设计机制的好处是:能够创建出一些列可复用的 directive,这些 directive 不会相互在拥有的属性值上产生串扰,也不会产生任何副作用。
AngularJS 独立作用域的数据绑定
在继承作用域中,我们可以选择子作用域直接操作父作用域数据来实现父子作用域的通信,而在独立作用域中,子作用域不能直接访问和修改父作用域的属性和值。为了能够使孤立作用域也能和外界通信,AngularJS 提供了三种方式用来打破独立作用域“孤立”这一限制。
单向绑定(@ 或者 @attr)