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會將控 制器注入到其值所指定的指令中,並作為當前指令的連結函式的第四個引數。

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