在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>
效果:

