angular指令詳解--自定義指令
自定義指令
directive()這個方法是用來定義指令的:
angular.module(‘myApp‘, []) .directive(‘myDirective‘, function ($timeout, UserDefinedService) { // 指令定義放在這裏 });
directive() 方法可以接受兩個參數:
1. name(字符串)
指令的名字,用來在視圖中引用特定的指令。
2. factory_function (函數)
這個函數返回一個對象,其中定義了指令的全部行為。$compile服務利用這個方法返回的對
象,在DOM調用指令時來構造指令的行為。
angular.application(‘myApp‘, []) .directive(‘myDirective‘, function() { // 一個指令定義對象 return { // 通過設置項來定義指令,在這裏進行覆寫 }; });
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(字符串)
restrict是一個可選的參數。它告訴AngularJS這個指令在DOM中可以何種形式被聲明。默
認AngularJS認為restrict的值是A,即以屬性的形式來進行聲明。
可選值如下:
E(元素)
<my-directive></my-directive>
A(屬性,默認值)
<div my-directive="expression"></div>
C(類名)
<div class="my-directive:expression;"></div>
M(註釋)
<--directive:my-directive expression-->
這些選項可以單獨使用,也可以混合在一起使用:
angular.module(‘myDirective‘, function(){
return {
restrict: ‘EA‘ // 輸入元素或屬性
};
});
上面的配置可以同時用屬性或註釋的方式來聲明指令:
<-- 作為一個屬性 -->
<div my-directive></div>
<-- 或者作為一個元素 -->
<my-directive></my-directive>
屬性是用來聲明指令最常用的方式,因為它能在包括老版本的IE瀏覽器在內的所有瀏覽器中
正常工作,並且不需要在文檔頭部註冊新的標簽。
terminal(布爾型)
terminal是一個布爾型參數,可以被設置為true或false。
這個參數用來告訴AngularJS停止運行當前元素上比本指令優先級低的指令。但同當前指令
優先級相同的指令還是會被執行。
如果元素上某個指令設置了terminal參數並具有較高的優先級,就不要再用其他低優先級的
指令對其進行修飾了,因為不會被調用。但是具有相同優先級的指令還是會被繼續調用。
使用了terminal參數的例子是ngView和ngIf。ngIf的優先級略高於ngView,如果ngIf的表
達式值為true,ngView就可以被正常執行,但如果ngIf表達式的值為false,由於ngView的優先
級較低就不會被執行。
template(字符串或函數)
template參數是可選的,必須被設置為以下兩種形式之一:
? 一段HTML文本;
? 一個可以接受兩個參數的函數,參數為tElement和tAttrs,並返回一個代表模板的字符
串。tElement和tAttrs中的t代表template,是相對於instance的。在討論鏈接和編譯
設置時會詳細介紹,模板元素或屬性與實例元素或屬性之間的區別。
AngularJS會同處理HTML一樣處理模板字符串。模板中可以通過大括號標記來訪問作用域,
例如{{ expression }}。
如果模板字符串中含有多個DOM元素,或者只由一個單獨的文本節點構成,那它必須被包
含在一個父元素內。換句話說,必須存在一個根DOM元素:
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>\
另外,註意每一行末尾的反斜線,這樣AngularJS才能正確解析多行字符串。在實際生產中,
更好的選擇是使用templateUrl參數引用外部模板,因為多行文本閱讀和維護起來都是一場噩夢。
templateUrl(字符串或函數)
templateUrl是可選的參數,可以是以下類型:
? 一個代表外部HTML文件路徑的字符串;
? 一個可以接受兩個參數的函數,參數為tElement和tAttrs,並返回一個外部HTML文件
路徑的字符串。
無論哪種方式, 模板的URL都將通過AngularJS內置的安全層, 特別是$getTrusted
ResourceUrl,這樣可以保護模板不會被不信任的源加載。
默認情況下,調用指令時會在後臺通過Ajax來請求HTML模板文件。有兩件事情需要知道。
? 在本地開發時,需要在後臺運行一個本地服務器,用以從文件系統加載HTML模板,否則
會導致Cross Origin Request Script(CORS)錯誤。
? 模板加載是異步的,意味著編譯和鏈接要暫停,等待模板加載完成。
通過Ajax異步加載大量的模板將嚴重拖慢一個客戶端應用的速度。為了避免延遲,可以在部
署應用之前對HTML模板進行緩存。在大多數場景下緩存都是一個非常好的選擇,因為AngularJS
通過減少請求數量提升了性能。
模板加載後,AngularJS會將它默認緩存到$templateCache服務中。在實際生產中,可以提
前將模板緩存到一個定義模板的JavaScript文件中,這樣就不需要通過XHR來加載模板了。
replace(布爾型)
replace是一個可選參數,如果設置了這個參數,值必須為true,因為默認值為false。默
認值意味著模板會被當作子元素插入到調用此指令的元素內部:
<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>
angular指令詳解--自定義指令