原文: www.jianshu.com/p/d55293715…javascript
選這本書就是由於朋友們都推薦這本, 並且講的還不錯, 最重要的是他們有資源, O(∩_∩)O哈哈~html
首先介紹一下本書中關於指令的知識結構:java
用過HTML的都知道, 每每在實現一些特殊功能的時候, 原有的HTML標籤並不徹底能知足設計要求, 這時候指令就派上用場了; 指令本質上就是擴展一些自定義的HTML元素以實現一些特定的功能;git
AngularJS事實上也是在原生JS的基礎上進行一些擴展和優化, 天然就會包括一些自定義的內置指令; 除了form和a等一些重載了原生的HTML元素, 其餘的內置指令一般以ng做爲前綴; 這樣作的目的也是對原生的一種優化, 好比經常使用的href指令, 不管裏面的連接是可用仍是, 不可用的, 當調用href的時候, 就會直接返回調用結果; 而ng-href指令則是當裏面的表達式調用而且返回一個值的時候纔開啓, 不然會是一個禁用狀態; 固然既然人家官方用ng這個前綴, 你就不要跟人家搶了, 換一個, 你們和諧一點兒;github
有網友總結了一下AngularJS的內置指令, 一共有63個;數組
簡單介紹一下form指令:app
<form>
First name:</br>
<input type="text" name="firstname" value="huo">
<br>
Last name:</br>
<input type="text" name="lastname" value="yu">
<br><br>
<input type="submit" value="Submit">
</form>複製代碼
效果圖:框架
要注意一下幾點:ionic
本書中對指令的定義是在特定DOM元素上運行的函數, 指令能夠擴展這個元素的功能;
在Angular中是經過directive()這個模塊來定義指令的;而directive()能夠接受兩個參數:函數
angular.application('myApp', [])
.directive('myDirective', function() {
// 一個指令定義對象
return {
// 經過設置項來定義指令, 在這裏進行填寫
};
});複製代碼
在HTML中調用就行:<div my-directive></div>複製代碼
這些選項能夠單獨使用, 也能夠混合使用;
2.2 優先級(數值型)
因爲考慮到性能問題, ngRepeat被設置成全部內置指令中優先級最高的; 固然若是兩個元素的優先級同樣, 會執行先聲明的那個;
2.3 terminal(布爾型)
它用來告訴AngularJs中止運行當前元素上比本指令優先級低的指令, 但當優先級相同的狀況仍是會運行;
例如:ngView和ngIf, ngIf的優先級略高於ngView, 若是ngIf表達式爲true, ngView就能夠被正常執行; 但若是ngIf的表達式爲false, ngView就不會被執行;
2.4 template(字符串或函數)
template參數必須被設置成如下兩種形式之一:
2.5 templateUrl(字符串或函數)
templateUrl參數能夠是如下形式:
2.6 replace(布爾型)
replace是個可選參數, 默認爲false; 當設置爲true後
.directive('someDirective', function() {
return {
replace: true
template: '<div>looking for something<div>'
};
});複製代碼
輸出結果爲:
<div>looking for something<div>複製代碼
2.7 scope參數(布爾型或對象)
scope參數有三種取值方式;
2.7.1 false(默認值)
直接使用父scope, 內部並無一個新的scope,它和指令之外的代碼共享同一個scope。
①指令
app.directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
templateUrl: '../templates/my_template.html',
scope: false, // 默認值
controller: null
}
});複製代碼
②指令模板(my_template.html)
<div>
<!--這裏ng-model綁定的input,就是父scope的變量input-->
<p>自定義指令scope:<input type="text" ng-model="input"></p>
<p>結果:{{input}}</p>
</div>複製代碼
③指令的使用(index.html)
<body ng-app="scopeTest" ng-controller="scopeTestStr">
<p>父scope:<input type="text" ng-model="input"></p>
<!--自定義指令-->
<my-directive></my-directive>
</body>複製代碼
效果以下:
2.7.2 true(繼承父scope)
當設置爲true的時候, 會從父做用域繼承並建立一個新的做用域對象;
參照值爲false的狀況, 只是將值改成true; 效果以下:
2.7.3 { }
建立一個新的"隔離"scope,但仍可與父scope通訊;
隔離的scope,一般用於建立可複用的指令,也就是它不用管父scope中的model。然而雖說是「隔離」,但一般咱們仍是須要讓這個子scope跟父scope中的變量進行綁定。綁定的策略有3種:
①@ 單項綁定
<body ng-app="scopeTest">
<!--外部scope-->
<p>父scope:<input type="text" ng-model="input"></p>
<!--內部隔離scope-->
<my-directive my-text="{{input}}"></my-directive>
<script> var app = angular.module('scopeTest', []); app.directive('myDirective', function () { return { restrict: 'E', replace: true, template: '<p>自定義指令scope:<input type="text" ng-model="myText"></p>', scope: { myText: '@' } } }); </script>
</body>複製代碼
效果圖:
②= 雙向綁定
<body ng-app="scopeTest">
<!--外部scope-->
<p>父scope:<input type="text" ng-model="input"></p>
<!--內部隔離scope-->
<!--注意這裏,由於是雙向綁定,因此這裏不要「{{}}」這個符號-->
<my-directive my-text="input"></my-directive>
<script> var app = angular.module('scopeTest', []); app.directive('myDirective', function () { return { restrict: 'E', replace: true, template: '<p>自定義指令scope:<input type="text" ng-model="myText"></p>', scope: { myText: '=' // 這裏改爲了雙向綁定 } } }); </script>
</body>複製代碼
效果圖:
③& 內部scope的函數返回值和外部scope綁定
<body ng-app="scopeTest">
<!--外部scope-->
<p>父scope:<input type="text" ng-model="input"></p>
<!--內部隔離scope-->
<!--注意這裏,函數名字也要用 連字符命名法-->
<my-directive get-my-text="input"></my-directive>
<script> var app = angular.module('scopeTest', []); app.directive('myDirective', function () { return { restrict: 'E', replace: true, template: '<p>結果:{{ getMyText() }}</p>', scope: { getMyText: '&' // 這裏改爲了函數返回值的綁定 } } }); </script>
</body>複製代碼
效果圖:
2.8 transclude(布爾型)
默認爲false; 只有當你但願建立一個能夠包含任意內容的指令的時候纔會爲true; 代碼以下所示:
app.directive('myDirective', function() {
return {
restrict: 'AE',
transclude: true,
template: "<div> hellow angular ! <div ng-transclude></div></div>"
}
});複製代碼
2.9 controller(字符串或函數)
指令內部的controller, 暴露一些public方法給內部指令使用;
①字符串;
angular.module('myApp', [])
.directive('myDirective', function() {
restrict: 'A', // 始終須要
controller: 'SomeController'
})
// 在應用中其餘地方定義該控制器
angular.module('myApp')
.controller('SomeController', function($scope, $element, $attrs, $transclude) {
// 控制器邏輯
});複製代碼
②函數
能夠是指令內部經過匿名構造函數的方式來定義一個內聯的控制器;
angular.module('myApp',[])
.directive('myDirective', function() {
restrict: 'A',
controller:
function($scope, $element, $attrs, $transclude) {
// 控制器邏輯
}
});複製代碼
如今你也能夠知道, 控制器中還有其餘一些特殊的服務能夠注入到指令中, 這些服務有:
在控制器內部操做DOM和angular.js風格相悖的作法, 但經過鏈式函數就能夠實現這個需求; 例如在compile參數中使用transcludeFn是推薦的作法;
本文提供了一個添加超連接的例子:
angular.module('myApp')
.directive('link', function() {
return {
restrict: 'EA',
transclude: true,
controller:
function($scope, $element, $transclude, $log) {
$transclude(function(clone) {
var a = angular.element('<a>');
a.attr('href', clone.text());
a.text(clone.text()); 8 $log.info("Created new a tag in link directive");
$element.append(a);
});
}
};
});複製代碼
link函數能夠與控制器指令的控制器互換; 控制器用來提供指令間的複用行爲, 但連接函數只能在當前內部指令中定義行爲且沒法在指令間複用;
link函數能夠將指令互相隔離, 而controller則定義可複用的行爲;
下面附一張link函數與compile函數的比較圖:
2.10 require(字符串或數組)
字符串或數組的值會是當前指令做用域中使用的指令名稱, 即用來調用暴露的內部方法;
對於指令的學習, 書中提供了內部原理, 固然光這些仍是遠遠不夠, 附上一個第三方指令庫, 看看源碼, 體驗一下別人是怎麼寫的;
AngularUI