每当一个指令被创建的时候,都会面临一个选择:继承父作用域,还是创建一个自己的作用域。Angular为指令的scope参数提供了三种选择,分别是: false(继承), true(不继承), {},默认是false。
scope: false
直接使用父作用域中的变量
测试代码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> p { margin: 0; } .a { border: 1px solid black; } </style> </head> <body ng-app= "myApp"> <div ng-controller= "myCtrl"> <div class="a"> <p ng-bind= "name"></p> <p ng-bind= "age"></p> <input type="text" ng-model= "name"/> </div> <mydir></mydir> </div> </body> <script src="js/angular.js"></script> <script> var myApp= angular.module("myApp", []); myApp.controller("myCtrl", function($scope){ $scope.name= "bluce"; $scope.age= 20; $scope.changeAge= function(){ $scope.age= 21; } }); //创建指令 myApp.directive("mydir", function(){ return { restrict: "AE", scope: false, replace: true, template: "<div><p ng-bind= 'name'> </p><p ng-bind= 'age'></p> <input type= 'text' ng-model= 'name'/> </div>" } }); </script> </html>
页面如下:
我们在上下两个输入框中改变name,都能互相改变
scope: true
创建一个新的作用域,这个作用域继承自我们的父作用域
理想情况下: 编辑父/子作用域都只会在自己的范围生效
但有一个奇怪的现象:
刚进入页面,编辑父作用域,子作用域跟着发生改变,然后编辑子作用域,父作用域不发生改变,最后再编辑父作用域,子作用域不发生改变
可以这么理解: 当子作用域尚未开始编辑,会被认定为没有资格独立,当它开始改变,便能开始独立
scope:{}
创建隔离的作用域
通过向scope的{}中传入特殊的前缀标识符,来进行数据的绑定
我们使用了隔离的作用域,不代表我们不可以使用父作用域的属性和方法。
我们可以通过向scope
的{}
中传入特殊的前缀标识符(即prefix
),来进行数据的绑定。
下面我们来看看如何使用这些前缀标识符:
@ 它将本地作用域和DOM中的属性值单向绑定起来(子作用域无法改变父作用域,父作用域能改变子作用域),且这个属性值必须是父作用域的
语法: <div my-dir the-name= "{{name}}"></div> //dom元素的命名用"-"连接
父作用域: $scope.name= "amy"
//directive的命名采用驼峰命名
myApp.direcitve("myDir", function(){
return {
restrict: "A",
scope: {
name: "@theName"
},
template: "<span ng-bind= 'name'></span>"
}
})
= 与@不同的是,@是针对字符串的传递,=是针对对象的引用,它属于双向绑定
语法:
<my-dir pre-person= "person"></my-dir>
父作用域:
$scope.person= {name: "amy", age: 21}
directive:
myApp.directive("myDir", function(){
return {
restrict: "E",
scope: {
person: "=prePerson"
},
template: "<input type= 'text' ng-model= 'person.age'/>"
}
})
& 是对方法的引用
语法:
<my-dir the-change-job= "changeJob()"></div>
父作用域:
$scope.changeJob= function(){$scope.job.name= "PE"}
direcitve:
myApp.directive("myDir", function(){
return {
restrict: "E",
scope: {
changeJob: "&theChangeJOb"
},
template: "<input type= 'button' value= '改变工作' ng-click= 'changeJob()'>"
}
})
来一起合起来的例子:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> p { margin: 0; } .a { border: 1px solid black; } </style> </head> <body ng-app= "myApp"> <div ng-controller= "myCtrl"> <div class="a"> <p ng-bind= "name"></p> <p ng-bind= "age"></p> <input type="text" ng-model= "name"/> <p ng-bind= "job.name"></p> <input type="text" ng-model= "job.name"/> </div> <my-dir the-name= "{{name}}" the-job= "job" the-change-job= "changeJob()"></my-dir> </div> </body> <script src="js/angular.js"></script> <script> var myApp= angular.module("myApp", []); myApp.controller("myCtrl", function($scope){ $scope.name= "bluce"; $scope.age= 20; $scope.job= {name: "engineer", time: 3}; $scope.changeJob= function(){ $scope.job.name= "PE"; } }); //创建指令 myApp.directive("myDir", function(){ var a= { restrict: "AE", scope: { name: '@theName', job: '=theJob', changeJob: '&theChangeJob' }, replace: true, template: "<div><p ng-bind= 'name'></p> <input type= 'text' ng-model= 'name'/> <p ng-bind= 'job.name'></p> <input type= 'text' ng-model= 'job.name'/> <input type= 'button' value= '改变工作' ng-click= 'changeJob()'/> </div>" }; return a; }); </script> </html>