angular自定義指令詳解

NO IMAGE

在運用angularjs的時候,運用自定義指令可以寫一些元件,非常方便。這裡給大家分享一些關於angular自定義指令的知識。

1. 定義

對於指令,可以把它簡單的理解成在特定DOM元素上執行的函式,指令可以擴充套件這個元素 的功能。

2.定義指令的方法:

angular.module('myApp', []) 
.directive('myDirective', function ($timeout, UserDefinedService) { 
    // 指令定義放在這裡 
}); 

第一個引數,指令的名字myDirective 用來在檢視中引用特定的指令。
第二個引數是一個函式,這個函式返回一個物件,$compile服務利用這個方法返回的對 象,在DOM呼叫指令時來構造指令的行為。

3.指令設定的選項

angular.module('myApp', []) 
.directive('myDirective', function() { 
    return { 
        restrict: String, 
        priority: Number, 
        terminal: Boolean, 
        template: String or Template Function: 
            function(tElement, tAttrs) (...}, 
        templateUrl: String, 
        replace: Boolean or String, 
        scope: Boolean or Object, 
        transclude: Boolean, 
        controller: String or  
        function(scope, element, attrs, transclude, otherInjectables) { ... }, 
        controllerAs: String, 
        require: String, 
        link: function(scope, iElement, iAttrs) { ... }, 
        compile: // 返回一個物件或連線函式,如下所示: 
            function(tElement, tAttrs, transclude) { 
                return { 
                    pre: function(scope, iElement, iAttrs, controller) { ... }, 
                    post: function(scope, iElement, iAttrs, controller) { ... } 
                } 
                // 或者 
                return function postLink(...) { ... } 
           } 
    }; }); 

restrict 指令在DOM中可以何種形式被引用或宣告

可選值如下: ( 可組合使用 )

E(元素) <my-directive></my-directive>
A(屬性,預設值) <div my-directive=”expression”></div>
C(類名) <div class=”my-directive:expression;”></div>
M(註釋) <–directive:my-directive expression–>

priority 優先順序 用來表示指令使用的優先順序
如果一個元素上具有兩個優先順序相同的指令,宣告在前面的那個會被優先呼叫。如果其中一 個的優先順序更高,則不管宣告的順序如何都會被優先呼叫:具有更高優先順序的指令總是優先執行。

terminal 用來告訴AngularJS停止執行當前元素上比本指令優先順序低的指令。但同當前指令 優先順序相同的指令還是會被執行。

<div ng-app="myApp" ng-controller="myCtr">
<!--此處在div上使用了兩個自定義指令,作為屬性存在,但directiveOne優先順序高,而且設定了terminal屬性,所以directiveSec指令並不會執行-->
   <div directive-Sec directive-One>
    這是自定義指令
   </div>    
</div>
var myCtr=["$scope",function($scope){}]
var app=angular.module("myApp",[]);
app.controller("myCtr",myCtr);
app.directive("directiveOne",function(){
return {
    restrict: "ECMA", 
    priority: 2, 
    terminal: true, 
    template:function(tElement, tAttrs){
        tElement[0].style.fontSize="18px"; //設定字型
    }
}
});
app.directive("directiveSec",function(){
return {
    restrict: "ECMA", 
    priority: 1, 
    template:function(tElement, tAttrs){
        tElement[0].style.color="red"; //設定顏色
    }
}
});

template
用來表示模板,可以是一段字串,如“<h1>這是自定義指令</h2>”,也可以是一個函式,可以參考上面的例子

template:function(tElement, tAttrs){
//tElement表示當前元素,是一個陣列,tAttrs表示該元素的屬性,是一個物件
   tElement[0].style.color="red"; //設定顏色
}

templateUrl 用來表示模板,與上面的template功能相似,但表示路徑,可以是外部HTML檔案路徑的字串也可以是一個可以接受兩個引數的函式,引數為tElement和tAttrs,並返回一個外部HTML檔案 路徑的字串。

replace 預設為false,模板會被當作子元素插入到呼叫此指令的元素內部,為true,則直接替換此元素

<div some-directive></div> 
.directive('someDirective', function() { 
return { 
    template: '<div>some stuff here<div>' 
}; }); 
<!-- 呼叫指令之後的結果如下(這是預設replace為false時的情況):  -->
<div some-directive> 
<div>some stuff here<div> 
</div> 


<!-- 如果replace被設定為了true:  -->
.directive('someDirective', function() { 
return { 
    replace: true // 修飾過 
    template: '<div>some stuff here<div>' 
}; }); 
<!-- 指令呼叫後的結果將是:  -->
<div>some stuff here<div> 

scope

(1)當scope設定為true時,會從父作用域繼承並建立一個新的作用域物件。
(2) 預設為false,並不會建立新的作用域物件,直接使用父scope。
(3)設定為{},表示隔離作用域,指令的 模板就無法訪問外部作用域了

var myCtr=["$scope",function($scope){
    $scope.name="father controller!!"
}]
var app=angular.module("myApp",[]);
app.controller("myCtr",myCtr);
app.directive("directiveOne",function(){
    return {
        restrict:"ECMA",
        template: '<div>這是自定義指令{{name}}<div>',
        scope:{},
        controller:function($scope){
            console.log($scope.name);//列印出來為undefined,因為無法訪問尾部作用域了
        }
    }
});

當然,AngularJS提供了幾種方法能夠將指令內部的隔離作用域,同指令外部的作用域進行資料繫結。
(a)@ (or @attr) 單向繫結,外部scope能夠影響內部scope,但反過來不成立

      <body>
    <div ng-app="myApp" ng-controller="myCtr">
        <input type="" name="" ng-model="value">
        <!-- 注意此處的svalue要寫成s-Value,不然沒效果-->
          <directive-One s-Value="{{value}}">
              
          </directive-One>
    </div>
<!--  -->
</body>
<script type="text/javascript">
    var myCtr=["$scope",function($scope){
        $scope.value="";
    }]
    var app=angular.module("myApp",[]);
    app.controller("myCtr",myCtr);
    app.directive("directiveOne",function(){
        return {
            restrict:"ECMA",
            template: '<div>這是自定義指令<input type="" name="" ng-model="sValue">{{sValue}}<div>',
            scope:{
                sValue:"@"
            },
            controller:function($scope){
                $scope.sValue="";
                console.log($scope.sValue);
            }
        }
    });

</script>

(b)= (or =attr)  雙向繫結,外部scope和內部scope的model能夠相互改變

    <body>
        <div ng-app="myApp" ng-controller="myCtr">
            <input type="" name="" ng-model="value">
            <!-- = 前面的value表示自定義指令自己的屬性名,後面的value表示父作用域的value -->
              <directive-One value="value">
                  
              </directive-One>
        </div>
    
    </body>
    <script type="text/javascript">
        var myCtr=["$scope",function($scope){
            $scope.value="1";
        }]
        var app=angular.module("myApp",[]);
        app.controller("myCtr",myCtr);
        app.directive("directiveOne",function(){
            return {
                restrict:"ECMA",
                template: '<div>這是自定義指令<input type="" name="" ng-model="value">{{value}}<div>',
                scope:{
                    value:"="
                },
                controller:function($scope){
                    $scope.value="";
                    console.log($scope.value);
                }
            }
        });
    
    </script>

    ![圖片描述][1]
    上面的輸入框輸入,下面會變,下面的輸入框輸入上面的也會變

    (c)& (or &attr)  把內部scope的函式的返回值和外部scope的任何屬性繫結起來

controller
controller引數可以是一個字串或一個函式。當設定為字串時,會以字串的值為名字, 來查詢註冊在應用中的控制器的建構函式.當為函式時,可以像平時寫控制器那樣寫,可以將任意可以被注入的AngularJS服務傳遞給控制器

controllerAs(字串)
controllerAs引數用來設定控制器的別名,可以以此為名來發布控制器,並且作用域可以訪 問controllerAs。這樣就可以在檢視中引用控制器,甚至無需注入$scope。

require
require引數可以被設定為字串或陣列,字串代表另外一個指令的名字。require會將控 制器注入到其值所指定的指令中,並作為當前指令的連結函式的第四個引數。

字串或陣列元素的值是會在當前指令的作用域中使用的指令名稱。