之前我們已經介紹了所有的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