带你走近AngularJS - 体验指令实例
之前我们已经介绍了所有的AngularJS 基础知识,下面让我们通过实例来加深记忆,体验自定义指令的乐趣。
带你走近AngularJS系列:
- 带你走近AngularJS - 基本功能介绍 http://www.linuxidc.com/Linux/2014-05/102140.htm
- 带你走近AngularJS - 体验指令实例 http://www.linuxidc.com/Linux/2014-05/102141.htm
- 带你走近AngularJS - 创建自定义指令 http://www.linuxidc.com/Linux/2014-05/102142.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标记更少,看起来清晰且易维护。
下面,让我们看下指令写法。
首先,我们定义模块"btstAccordion" 指令:
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 29 30 31 32 33 34 35 36 | 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拥有idvar id = element.attr("id");if (!id) {id = "btst-acc" + scope.$id;element.attr("id", id);}// set data-parent and href attributes on accordion-toggle elementsvar 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 startarr = element.find(".accordion-body");$(arr[0]).addClass("in"); // expand first panefor (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 27 | btst.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 Maps 指令
下一个例子是创建Google地图的指令:
