在AngularJS中,除了内置指令如ng-click等,我们还可以自定义指令。自定义指令,是为了扩展DOM元素的功能。代码中,通过指定directive中的restrict属性,来决定这个指令是作为标签(E)、属性(A)、属性值(C)、还是注释(M)。
二、scope属性的3种取值:
说明:为了探究scope取值对指令的影响,这里举的例子中,自定义指令都是作为DOM的tag使用的,即restrict属性为“E”。指令的名称为“my-directive(myDirective)”。
1、false(默认值):直接使用父scope。比较“危险”。
可以理解成指令内部并没有一个新的scope,它和指令以外的代码共享同一个scope。例子:
(1)指令的定义,app.js:
app.directive('myDirective', function() { return { restrict: 'E', replace: true, templateUrl: '../templates/my_template_01.html', scope: false, // 默认值 controller: null } });
(2)指令模板,my_template_01.html:
1 <div> 2 <!--这里ng-model绑定的input,就是父scope的变量input--> 3 <p>自定义指令scope:<input type="text" ng-model="input"></p> 4 5 <p>结果:{{input}}</p> 6 </div>
(3)指令的使用,index.html:
1 <body ng-app="watchDemo" ng-controller="controller01"> 2 <p>父scope:<input type="text" ng-model="input"></p> 3 4 <!--自定义指令--> 5 <my-directive></my-directive> 6 </body>
(4)效果:
可以看到,因为是同一个scope,所以无论是改变my-directive里面还是外面的输入框中的文字,都会改变这个scope中的“input”的值。
2、true:继承父scope
(1)指令的定义,app.js:
app.directive('myDirective', function() { return { restrict: 'E', replace: true, templateUrl: '../templates/my_template_01.html', scope: true, // 只是改动了这里 controller: null } });
(2)指令模板,my_template_01.html:
1 <div> 2 <!--这里绑定的同名的input,在继承的(子)scope中--> 3 <p>自定义指令scope:<input type="text" ng-model="input"></p> 4 5 <p>结果:{{input}}</p> 6 </div>
(3)指令的使用,index.html,没有变动:
1 <body ng-app="watchDemo" ng-controller="controller01"> 2 <p>父scope:<input type="text" ng-model="input"></p> 3 4 <!--自定义指令--> 5 <my-directive></my-directive> 6 </body>
(4)效果:
一开始是绑定在父scope中,但当修改位于自定义指令中的输入框时,子scope就被创建并继承父scope了。之后,修改父scope并不能影响input的值,而修改子scope就可以改变input的值了。如图:
3、{ }:创建一个新的“隔离”scope,但仍可与父scope通信
隔离的scope,通常用于创建可复用的指令,也就是它不用管父scope中的model。然而虽然说是“隔离”,但通常我们还是需要让这个子scope跟父scope中的变量进行绑定。绑定的策略有3种:
- @:单向绑定,外部scope能够影响内部scope,但反过来不成立
- =:双向绑定,外部scope和内部scope的model能够相互改变
- &:把内部scope的函数的返回值和外部scope的任何属性绑定起来
(1)@:单向绑定
示例代码:
1 <body ng-app="watchDemo"> 2 <!--外部scope--> 3 <p>父scope:<input type="text" ng-model="input"></p> 4 <!--内部隔离scope--> 5 <my-directive my-text="{{input}}"></my-directive> 6 7 <script> 8 var app = angular.module('watchDemo', []); 9 app.directive('myDirective', function () { 10 return { 11 restrict: 'E', 12 replace: true, 13 template: '<p>自定义指令scope:<input type="text" ng-model="myText"></p>', 14 scope: { 15 myText: '@' 16 } 17 } 18 }); 19 </script> 20 </body>
效果:
(2)=:双向绑定
示例代码:
1 <body ng-app="watchDemo"> 2 <!--外部scope--> 3 <p>父scope:<input type="text" ng-model="input"></p> 4 5 <!--内部隔离scope--> 6 <!--注意这里,因为是双向绑定,所以这里不要“{{}}”这个符号--> 7 <my-directive my-text="input"></my-directive> 8 9 <script> 10 var app = angular.module('watchDemo', []); 11 app.directive('myDirective', function () { 12 return { 13 restrict: 'E', 14 replace: true, 15 template: '<p>自定义指令scope:<input type="text" ng-model="myText"></p>', 16 scope: { 17 myText: '=' // 这里改成了双向绑定 18 } 19 } 20 }); 21 </script> 22 </body>
效果:
(3)&:内部scope的函数返回值和外部scope绑定
示例代码:
<body ng-app="watchDemo"> <!--外部scope--> <p>父scope:<input type="text" ng-model="input"></p> <!--内部隔离scope--> <!--注意这里,函数名字也要用 连字符命名法--> <my-directive get-my-text="input"></my-directive> <script> var app = angular.module('watchDemo', []); app.directive('myDirective', function () { return { restrict: 'E', replace: true, template: '<p>结果:{{ getMyText() }}</p>', scope: { getMyText: '&' // 这里改成了函数返回值的绑定 } } }); </script> </body>
效果: