1. 程式人生 > >AngularJS自定義指令directive:scope屬性

AngularJS自定義指令directive:scope屬性

一、介紹:

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

<div>
    <!--這裡ng-model繫結的input,就是父scope的變數input-->
<p>自定義指令scope:<input type="text" ng-model="input"></p> <p>結果:
{{input}}</p> </div>

(3)指令的使用,index.html:

<body ng-app="watchDemo" ng-controller="controller01">
    <p>父scope:<input type="text" ng-model="input"></p>

    <!--自定義指令-->
<my-directive></my-directive> </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:

<div>
    <!--這裡繫結的同名的input,在繼承的(子)scope中-->
    <p>自定義指令scope:<input type="text" ng-model="input"></p>

    <p>結果:{{input}}</p>
</div>

(3)指令的使用,index.html,沒有變動:

<body ng-app="watchDemo" ng-controller="controller01">
    <p>父scope:<input type="text" ng-model="input"></p>

    <!--自定義指令-->
    <my-directive></my-directive>
</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)@:單向繫結

示例程式碼:

<body ng-app="watchDemo">
    <!--外部scope-->
    <p>父scope:<input type="text" ng-model="input"></p>
    <!--內部隔離scope-->
    <my-directive my-text="{{input}}"></my-directive>

    <script>
        var app = angular.module('watchDemo', []);
        app.directive('myDirective', function () {
            return {
                restrict: 'E',
                replace: true,
                template: '<p>自定義指令scope:<input type="text" ng-model="myText"></p>',
                scope: {
                    myText: '@'
                }
            }
        });
    </script>
</body>

效果:
這裡寫圖片描述

(2)=:雙向繫結

示例程式碼:

<body ng-app="watchDemo">
    <!--外部scope-->
    <p>父scope:<input type="text" ng-model="input"></p>

    <!--內部隔離scope-->
    <!--注意這裡,因為是雙向繫結,所以這裡不要“{{}}”這個符號-->
    <my-directive my-text="input"></my-directive>

    <script>
        var app = angular.module('watchDemo', []);
        app.directive('myDirective', function () {
            return {
                restrict: 'E',
                replace: true,
                template: '<p>自定義指令scope:<input type="text" ng-model="myText"></p>',
                scope: {
                    myText: '=' // 這裡改成了雙向繫結
                }
            }
        });
    </script>
</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>

這裡寫圖片描述