angular 自定義指令 Directive(詳解)

在angular中,Directive,自定義指令的學習,可以更好的理解angular指令的原理,當angular的指令不能滿足你的需求的時候,嘿嘿,你就可以來看看這篇文章,自定義自己的指令,可以滿足你的各種需求的指令。

  本篇文章的參考來自  AngularJS權威指南 ,

  文章中主要介紹指令定義的選項配置

  廢話不多說,下面就直接上代碼

//angular指令的定義,myDirective ,使用駝峯命名法
angular.module('myApp', [])
.directive('myDirective', function ($timeout, UserDefinedService) {
// 指令操作代碼放在這裏
});

//angular自定義指令 的使用,使用 “-” 來代替駝峯命名法
<div my-directive></div>
注意:爲了避免與未來的HTML標準衝突,給自定義的指令加入前綴來代表自定義的
命名空間。AngularJS本身已經使用了 ng- 前綴,所以可以選擇除此以外的名字。
在例子中我們使用 my- 前綴(比如 my-derictive ) 。

指令的生命週期開始於 $compile 方法並
結束於 link 方法

//自定義指令的全部可設置的屬性大致如下
指令的選項如下所示,每個鍵的值說明了可以將這個屬性設置爲何種類型或者什麼樣的
函數:
angular.module('myApp', [])
.directive('myDirective', function() {               //指令名稱myDirective
return {                //返回一個對象
restrict: String,      //可選字符串參數,可以設置這個指令在DOM中可以何種形式被聲明,
            //默認爲A(attr(當做標籤屬性來使用))<div my-directive></div> 
            // 設置爲“E”(ele,(直接當做標籤來使用)) <my-directive></my-directive>
            //C(類名)
            //<div class="my-directive:expression;"></div>
            //M(註釋)
            //<--directive:my-directive expression-->
            //這些選項可以單獨使用,也可以混合在一起使用:
            //angular.module('myDirective', function(){
            //    return {
            //        restrict: 'EA' // 輸入元素或屬性
            //    };
            //})

priority: Number, //優先級,可忽略,默認爲0, ngRepeat的優先級爲1000,這樣就可以保證在同一元素上,它總是在其他指令之前被調用。
terminal: Boolean,//(布爾型),true或false,如果爲false,則這個參數用來告訴AngularJS停止運行當前元素上比本指令優先級低的指令。優先級相同的指令還是會被執行。 ngIf 的優先級略高於 ngView ,
template: String or Template Function: //(字符串或函數)指令中的一個重要的一個屬性,必須被設置其中一種
                    //1,  一段HTML文本;
                    //2,可以接收兩個參數的函數,參數爲 tElement 和 tAttrs 
                    //在html模板中必須只有一個根html標籤,且如果有換行則需要使用“\”
                    //例如template: '\
                    //    <div> <-- single root element -->\
                    //        <a href="http://google.com">Click me</a>\
                    //        <h1>When using two elements, wrap them in a parent element</h1>\
                    //    </div>\
                    //function(tElement, tAttrs) (...},
                    //更好的選擇是使用 templateUrl 參數引用外部模板,參考下面的參數
templateUrl: String,        //(字符串或函數)1,外部路徑的字符串,2,接受兩個參數的函數,參數爲 tElement 和 tAttrs ,並返回一個外部HTML文件路徑的字符串
                //模板加載後,AngularJS會將它默認緩存到 $templateCache 服務中。(可以提前加載模塊到緩存中,提高加載速度)
replace: Boolean or String,  //(布爾型)默認爲false(模板內容會加載到標籤內部),true(模板內容會替換當前標籤)
scope: Boolean or Object,  //(布爾型或對象),默認爲false, 設置爲true 時,會從父作用域繼承並創建一個新的作用域對象。
            // ng-controller 的作用,就是從父級作用域繼承並創建一個新的子作用域。
            //如果要創建一個能夠從外部原型繼承作用域的指令,將 scope 屬性設置爲 true 
            //設置爲一個對象,則能設置 隔離作用域, scope 屬性設置爲一個空對象 {} 。如果這樣做了,指令的模板就無法訪問外部作用域了:
            //例如.directive('myDirective', function() {
            //        return {
            //            restrict: 'A',
            //            scope: {},
            //            priority: 100,
            //            template: '<div>Inside myDirective {{ myProperty }}</div>'
            //        };
            //    });

            //在scope對象中,還可以使用“@” “=” “&”,來設置模板中數據的作用域和綁定規則
            //"@"  本地作用域屬性:使用當前指令中的數據和DOM屬性的值進行綁定
            //“=” 雙向綁定:本地作用域上的屬性同父級作用域上的屬性進行雙向的數據綁定。
            //“&” 父級作用域綁定:通過 & 符號可以對父級作用域進行綁定
            //例如
            //scope: {
            //    ngModel: '=', // 將ngModel同指定對象綁定
            //    onSend: '&', // 將引用傳遞給這個方法
            //    fromName: '@' // 儲存與fromName相關聯的字符串
            //}

transclude: Boolean,  //默認爲false.只有當你希望創建一個可以包含任意內容的指令時, 才使用 transclude: true 。
            //如果指令使用了 transclude 參數,那麼在控制器(下面馬上會介紹)中就無法正常監聽數
            //據模型的變化了。
controller: String or function(scope, element, attrs, transclude, otherInjectables) { ... }, //(字符串或函數)註冊在應用中的控制器的構造函數
            //使用函數創建內聯控制器,例如
            //angular.module('myApp',[])
            //    .directive('myDirective', function() {
            //    restrict: 'A',
            //    controller:
            /    function($scope, $element, $attrs, $transclude) {
            //    // 控制器邏輯放在這裏
            //    }
            //})

controllerAs: String,   //可以在指令中創建匿名控制器,例如
            //.directive('myDirective', function() {
            //    return {
            //    restrict: 'A',
            //    template: '<h4>{{ myController.msg }}</h4>',
            //    controllerAs: 'myController',
            //    controller: function() {
            //        this.msg = "Hello World"
            //        }
            //    };
            //});    


require: String, //(字符串或數組)字符串代表另外一個指令的名字,如果沒有前綴,指令將會在自身所提供的控制器中進行查找,如果沒有找到任何控制器(或
        //具有指定名字的指令)就拋出一個錯誤。
        //例如
        //如果不使用 ^ 前綴,指令只會在自身的元素上查找控制器。
        //require: 'ngModel'
        // 使用 ?   如果在當前指令中沒有找到所需要的控制器,會將 null 作爲傳給 link 函數的第四個參數
        //require: '?ngModel'
        //使用  ^  如果添加了 ^ 前綴,指令會在上游的指令鏈中查找 require 參數所指定的控制器。
        //require: '^ngModel'
        // 使用 ^?  將前面兩個選項的行爲組合起來,我們可選擇地加載需要的指令並在父指令鏈中進行查找。
        //require: '^?ngModel',

link: function(scope, iElement, iAttrs) { ... }, //compile 選項本身並不會被頻繁使用,但是 link 函數則會被經常使用。
                        //當我們設置了 link 選項, 實際上是創建了一個 postLink() 鏈接函數, 以便 compile() 函數可以定義鏈接函數。
                        //compile 和 link 選項是互斥的。如果同時設置了這兩個選項,那麼會把 compile
                        //所返回的函數當作鏈接函數,而 link 選項本身則會被忽略。
                        //通常情況下,如果設置了 compile 函數,說明我們希望在指令和實時數據被放到DOM中之前
                        //進行DOM操作,在這個函數中進行諸如添加和刪除節點等DOM操作是安全的。
        //用 link 函數創建可以操作DOM的指令。
        //require 'SomeController',
        //link: function(scope, element, attrs, SomeController) {
            // 在這裏操作DOM,可以訪問required指定的控制器
        //}
compile: function(tElement, tAttrs, transclude) {  
        return {
            pre: function(scope, iElement, iAttrs, controller) { ... },
            post: function(scope, iElement, iAttrs, controller) { ... }
        }
        // 或者
        return function postLink(...) { ... }
    }
};
});


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章