带你走近AngularJS - 体验指令实例


之前我们已经介绍了所有的AngularJS 基础知识,下面让我们通过实例来加深记忆,体验自定义指令的乐趣。

带你走近AngularJS系列:

  1. 带你走近AngularJS - 基本功能介绍
  2. 带你走近AngularJS - 体验指令实例
  3. 带你走近AngularJS - 创建自定义指令

如何在 AngularJS 中对控制器进行单元测试

AngularJS 之 Factory vs Service vs Provider

手风琴指令

我们展示的第一个例子是手风琴效果指令:

效果图如下:

image
在线实例地址:手风琴指令

不使用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拥有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 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地图的指令:

image
Google Maps 指令

更多详情见请继续阅读下一页的精彩内容:

  • 1
  • 2
  • 3
  • 下一页

相关内容