之前我們已經介紹了所有的AngularJS 基礎知識,下面讓我們通過實例來加深記憶,體驗自定義指令的樂趣。
帶你走近AngularJS系列:
如何在 AngularJS 中對控制器進行單元測試 http://www.linuxidc.com/Linux/2013-12/94166.htm
AngularJS 之 Factory vs Service vs Provider http://www.linuxidc.com/Linux/2014-05/101475.htm
我們展示的第一個例子是手風琴效果指令:
效果圖如下:
在線實例地址:手風琴指令
不使用AngularJS的純HTML源碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28<div class="accordion" id="accordion2">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse"
data-parent="#accordion2" href="#collapseOne">
Collapsible Group Item #1
</a>
</div>
<div id="collapseOne" class="accordion-body collapse in">
<div class="accordion-inner">
Anim pariatur cliche...
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse"
data-parent="#accordion2" href="#collapseTwo">
Collapsible Group Item #2
</a>
</div>
<div id="collapseTwo" class="accordion-body collapse">
<div class="accordion-inner">
Anim pariatur cliche...
</div>
</div>
</div>
</div>
以上純 HTML源碼也可以實現手風琴效果,但是它僅僅是一些標記,包含了大量的鏈接和id,不利於維護。
使用AngularJS自定義指令結合以下HTML源碼同樣可以得到預期效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15<body ng-app="btst">
<h3>BootStrap手風琴指令</h3>
<btst-accordion>
<btst-pane title="<b>基本功能</b>" category="{name:'test'}">
<div>AngularJS......</div>
</btst-pane>
<btst-pane title="<b>創建自定義指令</b>">
<div>使用過 AngularJS ......</div>
</btst-pane>
<btst-pane title="<b>體驗實例</b>">
<div>之前我們已經介紹了所有的AngularJS......</div>
</btst-pane>
</btst-accordion>
</body>
這一版使用的HTML標記更少,看起來清晰且易維護。
下面,讓我們看下指令寫法。
var btst = angular.module("btst", []);
btst.directive("btstAccordion", function () {
return {
restrict: "E",
transclude: true,
replace: true,
scope: {},
template:
"<div class='accordion' ng-transclude></div>",
link: function (scope, element, attrs) {
// 確保 accordion擁有id
var id = element.attr("id");
if (!id) {
id = "btst-acc" + scope.$id;
element.attr("id", id);
}
// set data-parent and href attributes on accordion-toggle elements
var arr = element.find(".accordion-toggle");
for (var i = 0; i < arr.length; i++) {
$(arr[i]).attr("data-parent", "#" + id);
$(arr[i]).attr("href", "#" + id + "collapse" + i);
}
// set collapse attribute on accordion-body elements
// and expand the first pane to start
arr = element.find(".accordion-body");
$(arr[0]).addClass("in"); // expand first pane
for (var i = 0; i < arr.length; i++) {
$(arr[i]).attr("id", id + "collapse" + i);
}
},
controller: function () {}
};
});
由於擁有內部HTML內容,所以設置指令的transclude 屬性為true。模板使用ng-transclude 指令來聲明對應的顯示內容。由於模板中只有一個元素,所以沒有設置其他選項。
代碼中最有趣的部分是link 方法。它在參數element具有id時啟作用,如果沒有,會依據指令的 Scope自動創建ID。一旦元素擁有了ID值,方法將通過jQuery來選擇具有"accordion-toggle"類的子元素並且設置它的 "data-parent" 和 "href" 屬性。最後,通過尋找“accordion-body” 元素,並且設置"collapse" 屬性。
指令同時聲明了一個擁有空方法的controller 。聲明controller 是必要的,因為Accordion會包含子元素,子元素將檢測父元素的類型和controller 。
這一步比較容易,大多數操作將在這個模板中發生,但是它僅僅需要少量的代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27btst.directive('btstPane', function () {
return {
require: "^btstAccordion",
restrict: "E",
transclude: true,
replace: true,
scope: {
title: "@"
},
template:
"<div class='accordion-group'>" +
" <div class='accordion-heading'>" +
" <a class='accordion-toggle' data-toggle='collapse'>{{title}}</a>" +
" </div>" +
"<div class='accordion-body collapse'>" +
" <div class='accordion-inner' ng-transclude></div>" +
" </div>" +
"</div>",
link: function (scope, element, attrs) {
scope.$watch("title", function () {
// NOTE: this requires jQuery (jQLite won't do html)
var hdr = element.find(".accordion-toggle");
hdr.html(scope.title);
});
}
};
});
require 屬性值為"btstPane" ,所以該指令必須用於指令"btstAccordion"中。transclude 屬性為true表明選項卡包含HTML標簽。scope 下的 "title" 屬性將會被實例所替代。
這個例子中的模板比較復雜。注意我們通過ng-transclude 指令來標記元素接收文本內容。
模板中"{{title}}" 屬性將會顯示標簽名稱。目前我們僅僅實現了純文本顯示,沒有定義其樣式。我們使用link 方法可以替換標題為HTML源碼從而得到更豐富的樣式。
就這樣,我們完成了第一個具有實用價值的指令。它功能並不復雜但是足以展示一些AngularJS的重要知識點和技術細節:如何定義嵌套指令,如何生成唯一的元素ID,如何使用jQuery操作DOM以及如何使用$watch 方法監聽scope變量的變化。
下一個例子是創建Google地圖的指令:
Google Maps 指令
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-05/102142p2.htm