AngularJs自定義指令詳解
定義指令的方法:
angular.module('myApp', [])
.directive('myDirective', function () {
// 指令定義放在這裡
});
第一個引數,指令的名字myDirective 用來在檢視中引用特定的指令。第二個引數是一個函式,這個函式返回一個物件,$compile服務利用這個方法返回的對 象,在DOM呼叫指令時來構造指令的行為。
指令設定的選項
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(...) { ... } } }; });
1、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-->
2、priority 優先順序 用來表示指令使用的優先順序
如果一個元素上具有兩個優先順序相同的指令,宣告在前面的那個會被優先呼叫。如果其中一 個的優先順序更高,則不管宣告的順序如何都會被優先呼叫:具有更高優先順序的指令總是優先執行。
3、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"; //設定顏色 } } });
4、template
用來表示模板,可以是一段字串,如“<h1>這是自定義指令</h2>”,也可以是一個函式,可以參考上面的例子
template:function(tElement, tAttrs){
//tElement表示當前元素,是一個數組,tAttrs表示該元素的屬性,是一個物件
tElement[0].style.color="red"; //設定顏色
}
5、templateUrl 用來表示模板,與上面的template功能相似,但表示路徑,可以是外部HTML檔案路徑的字串也可以是一個可以接受兩個引數的函式,引數為tElement和tAttrs,並返回一個外部HTML檔案 路徑的字串。
6、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>
7、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的任何屬性繫結起來
8、controllercontroller引數可以是一個字串或一個函式。當設定為字串時,會以字串的值為名字, 來查詢註冊在應用中的控制器的建構函式.當為函式時,可以像平時寫控制器那樣寫,可以將任意可以被注入的AngularJS服務傳遞給控制器。
9、controllerAs(字串)
controllerAs引數用來設定控制器的別名,可以以此為名來發布控制器,並且作用域可以訪 問controllerAs。這樣就可以在檢視中引用控制器,甚至無需注入$scope。
10、require
require引數可以被設定為字串或陣列,字串代表另外一個指令的名字。require會將控 制器注入到其值所指定的指令中,並作為當前指令的連結函式的第四個引數。
字串或陣列元素的值是會在當前指令的作用域中使用的指令名稱。
轉自:https://segmentfault.com/a/1190000009820031