Angular之指令Directive用法詳解
項(xiàng)目籌備近期開(kāi)啟Angular學(xué)習(xí),指令比較難理解所以記錄備案,推薦視頻大漠窮秋 Angular實(shí)戰(zhàn) 由于篇幅過(guò)長(zhǎng),列舉大綱如下:

一、指令directive概述
指令可以對(duì)元素綁定事件監(jiān)聽(tīng)或者改變DOM結(jié)構(gòu)而使HTML擁有像jQuery一樣效果具有交互性。不同于jQuery,Angular設(shè)計(jì)核心思想是通過(guò)數(shù)據(jù)與模板的綁定,擺脫繁瑣的DOM操作,而將注意力集中在業(yè)務(wù)邏輯上。
幾種常見(jiàn)指令ng-app 指令用來(lái)指定ng的作用域是在那個(gè)標(biāo)簽以內(nèi)部分(<html ng-app="myApp">標(biāo)簽) ng-repeat迭代器指令可以重復(fù)標(biāo)記元素、ng-show指令可以根據(jù)條件是否顯示一個(gè)元素、ng-model指令具有雙向數(shù)據(jù)綁定特性、ng-controller 用來(lái)聲明一個(gè)需要和數(shù)據(jù)進(jìn)行綁定的模板區(qū)域
二、自定義指令directive之模式匹配restrict
直接上代碼體驗(yàn)一把,index.html
<!DOCTYPE html> <html ng-app="myModule"> <head> <meta charset="UTF-8"> <title>Angular指令--自定義標(biāo)簽</title> <script type="text/javascript" src="framework/1.3.0.14/angular.js"></script> </head> <body> <hello></hello> <div hello></div> <div class='hello'></div> <!-- directive:hello --> <div></div> <!--代碼模板template--> <script type="text/ng-template" id="hello_Angular.html"> <p>Hello Angular</p> </script> <!--代碼模板template--> </body> </html>
指令Directive.js
<script type="text/javascript">
//調(diào)用angular對(duì)象的module方法來(lái)聲明一個(gè)模塊,模塊的名字和ng-app的值對(duì)應(yīng)
var myModule = angular.module('myModule',[]);
/* restrict 屬性值說(shuō)明 <推薦使用EA>
* E--element元素 <hello></hello>
* A--attribute 屬性 <div hello></div>
* C-class 樣式類 <div class="hello"></div>
* M 注釋 <!-- directive:hello -->
*/
//指令--對(duì)元素綁定事件監(jiān)聽(tīng)或者改變DOM
myModule.directive('hello', function(){
return {
restrict: 'EACM',
templateUrl:'hello_Angular.html',
/*template : '<p>Hello Angular</p>',*/
replace: true
}
})
</script>
==========================================================
restrict---匹配模式說(shuō)明, 英文意思是"限制;約束;限定",這里指的是匹配我自定義的標(biāo)簽
==========================================================
•E 元素(element) <hello></hello>
•A 屬性(attribute) <div hello></div>
•C 樣式類(class) <div class="hello"></div>
•M 注釋 <!-- directive:hello --> 注意?。?!空格(不常用)
溫馨tips: 推薦使用EC或EA匹配模式
replace 是否替換元素的模式 replace:true瀏覽器DOM結(jié)構(gòu)如下

replace:false 或沒(méi)有replace屬性時(shí)瀏覽器DOM結(jié)構(gòu)如下

三、指令之嵌套變換transclude
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>transclude 嵌套變換</title>
<script type="text/javascript" src="framework/1.3.0.14/angular.js"></script>
</head>
<body>
<hello>這里是內(nèi)容哦.....</hello>
<div hello>這里是內(nèi)容哦hello....</div>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.directive('hello',function(){
return {
restrict: 'EA',
template: '<p>Hello World!!!<b ng-transclude></b></p>',
transclude: true, /*嵌套變換*/
replace: true /*替換*/
}
})
</script>
</body>
</html>
四、指令directive運(yùn)行原理
五、指令配置參數(shù)說(shuō)明
myModule.directive('namespaceDirectiveName', function factory(injectables) {
var directiveDefinitionObject = {
restrict: string,//指令的使用方式,包括標(biāo)簽,屬性,類,注釋
priority: number,//指令執(zhí)行的優(yōu)先級(jí)
template: string,//指令使用的模板,用HTML字符串的形式表示
templateUrl: string,//從指定的url地址加載模板或<script type="text/ng-template" id="string"></script>
replace: bool,//是否用模板替換當(dāng)前元素,若為false,則append在當(dāng)前元素上
transclude: bool,//是否將當(dāng)前元素的內(nèi)容轉(zhuǎn)移到模板中
scope: bool or object,//指定指令的作用域
controller: function controllerConstructor($scope, $element, $attrs, $transclude){...},//定義與其他指令進(jìn)行交互的接口函數(shù)
require: string,//指定需要依賴的其他指令
link: function postLink(scope, iElement, iAttrs) {...},//以編程的方式操作DOM,包括添加監(jiān)聽(tīng)器等
compile: function compile(tElement, tAttrs, transclude){
return: {
pre: function preLink(scope, iElement, iAttrs, controller){...},
post: function postLink(scope, iElement, iAttrs, controller){...}
}
}//編程的方式修改DOM模板的副本,可以返回鏈接函數(shù)
};
return directiveDefinitionObject;
});
六、指令與控制器的交互
index.html 如下
<!DOCTYPE html> <html ng-app="myApp"> <head> <meta charset="UTF-8"> <title>Directive指令與Controller控制器交互</title> <!--引入js庫(kù)anglarjs--> <script type="text/javascript" src="framework/1.3.0.14/angular.js"></script> <script type="text/javascript" src="js/Directive&Controller.js"></script> </head> <body> <div ng-controller="myAppCtrl"> <loader hello howToLoad="loadData()">數(shù)據(jù)加載......</loader> </div> <div ng-controller="myAppCtrl2"> <loader hello howToLoad="loadData2()">數(shù)據(jù)加載2......</loader> </div> </body> </html>
Directive&Controller.js
var myApp = angular.module('myApp', []);
myApp.controller('myAppCtrl', ['$scope', function($scope){
console.log($scope);
$scope.loadData = function(){
console.log('數(shù)據(jù)加載中.....');
}
}]);
myApp.controller('myAppCtrl2', ['$scope', function($scope){
console.log($scope);
$scope.loadData2 = function(){
console.log('數(shù)據(jù)加載中2.....');
}
}]);
//指令與控制器之間交互
myApp.directive('loader', function(){
return {
restrict: 'EA',
template: '<div ng-transclude></div>',
transclude: true,
replace: true,
/*scope: {}, 獨(dú)立scope*/
link: function(scope, element, attrs){
element.bind('mouseenter', function(){
/*這里調(diào)用controller中的方法三種方式*/
/*(1) scope.loadData();
(2) scope.$apply('loadData()');
(3) attrs.howtoload === 屬性上綁定的函數(shù)名稱*/
//屬性方式 注意坑?。?! howtoload 得小寫(xiě)
scope.$apply(attrs.howtoload);
})
}
}
})
實(shí)現(xiàn)的效果是當(dāng)鼠標(biāo)滑過(guò)div元素時(shí),調(diào)用一個(gè)加載數(shù)據(jù)的方法。
上述例子中定義了兩個(gè)控制器,然后兩個(gè)控制器中都使用了loader指令,并且,每個(gè)指令中都有一個(gè)參數(shù) howToLoad .
關(guān)于指令中的 link ,上面介紹運(yùn)行機(jī)制中可以了解到,link: function postLink(scope, element, attrs) {...}是用來(lái)操作dom和綁定監(jiān)聽(tīng)事件的。
link中會(huì)有三個(gè)參數(shù):scope(指令所屬的控制器中的 $scope 對(duì)象)、element(指令所屬dom元素)、attrs(dom元素所傳的參數(shù)
如howToLoad 參數(shù)給的值 loadData()
然后對(duì)于如何調(diào)用所需函數(shù),有兩種方法:
1> scope.loadData() 兩個(gè)控制器方法不一致時(shí),就不能用了
2> scope.$apply() $apply()方法會(huì)從所有控制器中找到多對(duì)應(yīng)的方法。這就實(shí)現(xiàn)了指令的復(fù)用。
明確對(duì)于控制器ng-controller都會(huì)創(chuàng)建屬于自己獨(dú)立的scope;對(duì)于指令若無(wú)scope:{}聲明會(huì)繼承控制器中的scope
七、指令與指令的交互
index.html
<!DOCTYPE html>
<html ng-app="myModule">
<head>
<meta charset="UTF-8">
<title>directive指令與directive指令之間的交互</title>
<!--引入第三方樣式庫(kù)bootstrap.min.css-->
<link rel="stylesheet" href="framework/bootstrap-3.0.0/css/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" />
<!--引入js庫(kù)anglarjs-->
<script type="text/javascript" src="framework/1.3.0.14/angular.js"></script>
<script type="text/javascript" src="js/Directive&Directive.js"></script>
</head>
<body>
<div class="row">
<div class="col-md-3">
<superman strength>動(dòng)感超人---力量</superman>
</div>
</div>
<div class="row">
<div class="col-md-3">
<superman strength speed>動(dòng)感超人2---力量+敏捷</superman>
</div>
</div>
<div class="row">
<div class="col-md-3">
<superman strength speed light>動(dòng)感超人3---力量+敏捷+發(fā)光</superman>
</div>
</div>
</body>
</html>
Directive&Directive.js
var myModule = angular.module('myModule',[]);
//指令與指令之間交互
myModule.directive('superman', function(){
return {
scope: {},/*獨(dú)立作用域*/
restrict: 'AE',
template: '<button class="btn btn-primary" ng-transclude></button>',
transclude: true,
controller: function($scope){ /*暴露controller里面方法*/
$scope.abilities = [];
this.addStrength = function(){
$scope.abilities.push('strength');
};
this.addSpeed = function(){
$scope.abilities.push('speed');
};
this.addLight = function(){
$scope.abilities.push('light');
};
},
link: function(scope, element, attrs, supermanCtr){
element.addClass = "btn btn-primary";
element.bind('mouseenter', function(){
console.log(scope.abilities);
})
}
}
})
myModule.directive('strength', function(){
return {
require: "^superman",/*require參數(shù)指明需要依賴的指令*/
link: function(scope, element, attrs, supermanCtr){
supermanCtr.addStrength();
}
}
});
myModule.directive('speed', function(){
return {
require: "^superman",
link: function(scope, element, attrs, supermanCtr){
supermanCtr.addSpeed();
}
}
});
myModule.directive('light', function(){
return {
require: "^superman",
link: function(scope, element, attrs, supermanCtr){
supermanCtr.addLight();
}
}
});
*require參數(shù)指明需要依賴的指令
*指令中的controller相當(dāng)于暴露里面方法,便于指令復(fù)用
八、scope作用域綁定策略
scope “@” 把當(dāng)前屬性作為字符串傳值
<!DOCTYPE html>
<html ng-app="myModule">
<head>
<meta charset="UTF-8">
<title>scope綁值策略一.'@'把當(dāng)前屬性作為字符串傳值</title>
<!--引入js庫(kù)anglarjs-->
<script type="text/javascript" src="framework/1.3.0.14/angular.js"></script>
<script type="text/javascript" src="js/Scope@.js"></script>
</head>
<body>
<div ng-controller="myAppCtrl">
<drink flavor="{{ctrFlavor}}"></drink>
</div>
</body>
</html>
Scope@.js
var myModule = angular.module('myModule', []);
myModule.controller('myAppCtrl',['$scope', function($scope){
console.log($scope);
$scope.ctrFlavor = "百事可樂(lè)";
}]);
myModule.directive('drink', function(){
return {
restrict: 'AE',
scope: { /*獨(dú)立scope作用域*/
flavor: '@'
},
replace:true,
template: '<p>{{flavor}}</p>'
//使用link進(jìn)行指令和控制器兩個(gè)作用域中數(shù)據(jù)的綁定。
//如果用scope中@的話,就不需要link這么麻煩了,angularJS會(huì)自動(dòng)進(jìn)行綁定
/*,
link:function(scope,element,attrs){
element.bind('mouseenter', function(){
})
scope.flavor = attrs.flavor;
}*/
}
})
scope “=” 與父scope屬性進(jìn)行雙向綁定
index.html
<!DOCTYPE html>
<html ng-app="myModule">
<head>
<meta charset="UTF-8">
<title>scope綁值策略二.'='與父scope中的屬性進(jìn)行雙向綁定</title>
<!--引入第三方樣式庫(kù)bootstrap.min.css-->
<link rel="stylesheet" href="framework/bootstrap-3.0.0/css/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" />
<!--引入js庫(kù)anglarjs-->
<script type="text/javascript" src="js/scope=.js"></script>
</head>
<body>
<div ng-controller="myModuleCtrl" class="col-sm-6">
<p>{{describe}}</p>
Ctrl--控制器:<br />
<input type="text" ng-model="ctrFlavor" class="form-control" />
<br />
<p>{{ctrFlavor}}</p>
Directive--指令:<br />
<drink flavor="ctrFlavor"></drink>
<p>{{flavor}}</p>
</div>
</body>
</html>
scope=.js
var myModule = angular.module('myModule', []);
myModule.controller('myModuleCtrl',['$scope', function($scope){
$scope.describe = "scope綁值策略二.=與父scope中的屬性進(jìn)行雙向綁定";
$scope.ctrFlavor = "可口可樂(lè)";
}]);
//=與父scope中的屬性進(jìn)行雙向綁定
myModule.directive('drink',function(){
return {
restrict: 'EA',
scope: { /*ng-isolate-scope 隔離作用域*/
flavor : '='
},
template: '<input type="text" class="form-control" ng-model="flavor" />'
/*replace:true*/
}
});
這個(gè)例子中有兩個(gè)輸入框,第一個(gè)綁定了myModuleCtrl控制器中的scope對(duì)象的ctrlFlavor 屬性。
第二個(gè)綁定的是指令中的flavor屬性。但是在drink 指令中 scope對(duì)象的flavor 屬性 用了 ”=“ ,
與父scope中的屬性進(jìn)行雙向數(shù)據(jù)綁定。所以兩個(gè)值有一個(gè)改動(dòng),另一個(gè)屬性值也會(huì)改動(dòng)。 簡(jiǎn)單理解為把兩個(gè)存放數(shù)據(jù)倉(cāng)庫(kù)給相等 A1 == B1
scope& '&'傳遞一個(gè)來(lái)自父scope的函數(shù),稍后調(diào)用
index.html
<!DOCTYPE html>
<html ng-app="myModule">
<head>
<meta charset="UTF-8">
<title>scope綁值策略三.'&'傳遞一個(gè)來(lái)自父scope的函數(shù),稍后調(diào)用</title>
<!--引入第三方樣式庫(kù)bootstrap.min.css-->
<link rel="stylesheet" href="framework/bootstrap-3.0.0/css/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" />
<!--引入js庫(kù)anglarjs-->
<script type="text/javascript" src="js/scope&.js"></script>
</head>
<body>
<div ng-controller="myModuleCtrl">
<greeting greet="sayHello(name)"></greeting>
<greeting greet="sayHello(name)"></greeting>
<greeting greet="sayHello(name)"></greeting>
</div>
<!--代碼模板template-->
<script type="text/ng-template" id="sayHello.html">
<div class="col-sm-12 container">
<form role = "form">
<div class = "form-group">
<input type="text" class="form-control" ng-model="userName" />
<button class="btn btn-primary" ng-click="greet({name:userName})">Greeting</button>
</div>
</form>
</div>
</script>
<!--代碼模板template-->
</body>
</html>
scope&.js
var myModule = angular.module('myModule', []);
myModule.controller('myModuleCtrl',['$scope', function($scope){
$scope.sayHello = function(name){
console.log('Hello'+name);
}
}]);
myModule.directive('greeting', function(){
return {
restrict: 'EA',
scope: { /*'&'傳遞一個(gè)來(lái)自父scope的函數(shù),稍后調(diào)用*/
greet : '&'
},
templateUrl: 'sayHello.html'
}
});
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
angularJS開(kāi)發(fā)注意事項(xiàng)
本篇文章給大家分享了angularJS開(kāi)發(fā)注意事項(xiàng)以及相關(guān)知識(shí)點(diǎn),對(duì)此有興趣的朋友參考學(xué)習(xí)下。2018-05-05
利用Angular2 + Ionic3開(kāi)發(fā)IOS應(yīng)用實(shí)例教程
這篇文章主要給大家介紹了關(guān)于利用Angular2 + Ionic3開(kāi)發(fā)IOS應(yīng)用的相關(guān)資料,文中通過(guò)示例代碼和圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01
詳解angularjs獲取元素以及angular.element()用法
本篇文章主要介紹了詳解angularjs獲取元素以及angular.element()用法 ,具有一定的參考價(jià)值,有興趣的可以了解一下2017-07-07
利用Angular2的Observables實(shí)現(xiàn)交互控制的方法
這篇文章主要介紹了利用Angular2的Observables實(shí)現(xiàn)交互控制的方法,我們主要針對(duì)一些在跟服務(wù)器端交互的時(shí)候遇到的問(wèn)題,來(lái)看看Observable給我們帶來(lái)的特性。感興趣的可以了解一下2018-12-12
Angular懶加載機(jī)制刷新后無(wú)法回退的快速解決方法
使用oclazyload懶加載angular的模塊,刷新頁(yè)面后,單擊回退按鈕無(wú)法返回上一個(gè)頁(yè)面.怎么回事呢?下面小編給大家?guī)?lái)了angular懶加載機(jī)制刷新后無(wú)法回退的快速解決方法,非常不錯(cuò),感興趣的朋友參考下2016-08-08
angularJS與bootstrap結(jié)合實(shí)現(xiàn)動(dòng)態(tài)加載彈出提示內(nèi)容
這篇文章主要介紹了angularJS與bootstrap結(jié)合實(shí)現(xiàn)動(dòng)態(tài)加載彈出提示內(nèi)容,通過(guò)bootstrp彈出提示。感興趣的朋友可以參考下本篇文章2015-10-10
AngularJS全局scope與Isolate scope通信用法示例
這篇文章主要介紹了AngularJS全局scope與Isolate scope通信用法,結(jié)合格式分析了全局scope和directive本地scope相關(guān)功能、通信用法與相關(guān)注意事項(xiàng),需要的朋友可以參考下2016-11-11

