AngularJS除了强大的自定义服务外,还有更强大的指令。本章我们将继续前面的内容,更进一步的学习AngularJS的指令。
AngularJS的指令(Directive)简介
指令是AngularJS中另一个主要的特性,指令的作用可以用一句话描述,就是可以给HTML元素赋予特殊或自定义的行为,比如监听事件、视图模板代理等。在上文中我们使用过的ng-app、ng-controller、ng-model就是AngularJS中的指令。
AngularJS指令的命名
指令的命名和使用写法比较有意思,一般情况下在定义指令时推荐使用驼峰命名法,比如ngModel、ngApp,但是在HTML中大小写是不敏感的,所以在HTML中使用指令时推荐使用小写字母加破折号的形式,比如ng-model、ng-app。除了使用小写破折号这种方式,还有以下几种使用写法:
- ng:model
- ng_model
- data-ng-bind
- x-ng-bind
大家可以根据自己喜好选择使用写法,但是尽量保持写法统一。
AngularJS指令的形式
在AngularJS中,指令有四种表现形式,既标签形式、标签属性形式、标签class名称形式、注释形式:
<my-dir></my-dir> <span my-dir="exp"></span> <!-- directive: my-dir exp --> <span class="my-dir: exp;"></span>
一般情况下,推荐使用标签形式和标签属性形式。
指令的使用
与Controller一样,指令也是通过AngularJS的Model创建的,使用directive(name, directiveFactory)方法创建指令,该方法有两个参数:
- 第一个参数为指令名称,命名规范在上文中已经说过了。
- 第二个参数是一个工厂函数,该函数需要返回一个对象,我们通过配置该对象中的不同属性从而告诉AngularJS内置的$compile服务实现指令的不同功能。
指令的类型
上文中说过指令的实现是通过工厂函数返回对象,然后通过配置对象的不同属性实现不同功能,所以设置指令的类型也是通过配置属性对象完成的:
var mainModule = angular.module("mainModule", []); mainModule.directive("myDirective", function() { return { restrict: "A" }; }); mainModule.directive("myDirective1", function() { return { restrict: "E" }; }); mainModule.directive("myDirective2", function() { return { restrict: "AE" }; });
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Demo for Directive</title> <script src="../angular-1.5.8.js"></script> <script src="modules.js"></script> </head> <body ng-app="mainModule"> <div my-directive></div> <my-directive1></my-directive1> <my-directive2></my-directive2> <!-- <div my-directive2></div> --> </body> </html>
从上面的示例代码可以看出,可以通过配置返回对象的restrict属性设置指令的类型,可配置的值分别为:
- "A":代表且仅可代表标签属性类型的指令。
- "E":代表且仅可代表标签类型的指令。
- "C":代表且仅可代表class名称类型的指令。
- "M":代表且仅可代表注释类型的指令。
如果想设置一个多类型的指令,那么可以将类型标识写在一起,比如"AEC"代表既是标签属性类型,又是标签类型,还是class名称类型。如果不配置restrict属性,那么表示指令的类型为默认的"AE"类型。
通过指令封装UI模板
在前端应用的开发过程中,不同的页面常有很多一样的UI元素,如果每个页面都写一遍,那么在维护时就常会牵一发而动全身,AngularJS中的指令可以很好的解决这个问题,它可以将UI片段封装为一个指令,从而可以在不同的页面中复用,那么在维护时就是四两拨千斤的效果。下面来看看如何实现模板指令:
var mainModule = angular.module("mainModule", []); mainModule.controller("MyController", function() { this.name = "Jason"; this.job = "Developer"; }); mainModule.directive("myDirective", function() { return { template: "Name: {{mc.name}}, Job: {{mc.job}}" }; });
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Demo for Directive</title> <script src="../angular-1.5.8.js"></script> <script src="modules.js"></script> </head> <body ng-app="mainModule"> <div ng-controller="MyController as mc"> <my-directive></my-directive> <!-- <div my-directive></div> --> </div> </body> </html>
上面的代码示例中,我们将本该写在HTML中的展示代码设置给了返回对象的template属性。为了能更好的管理UI模板,我们还可以将UI展示代码提炼成单独的HTML模板文件,并可以使用指令的templateUrl属性设置HTML模板文件名称,这样便可以大大降低指令和UI模板的耦合度:
mainModule.directive("myDirective", function() { return { templateUrl: "myTemplate.html" }; });
<!-- myTemplate.html --> Name: {{mc.name}}, Job: {{mc.job}}
那么问题来了,如果UI模板文件很多的话,按上面的方法就要写很多个对应的指令,而且只是UI模板文件名称不一样而已,实在有点冗余。AngularJS提供了另外一种解决方法,那就是可以通过给模板指令设置相关属性,从而动态的加载UI模板文件,我们来看看如何实现:
// modules.js var mainModule = angular.module("mainModule", []); mainModule.controller("MyController", function() { this.name = "Jason"; this.job = "Developer"; }); mainModule.directive("myDirective", function() { return { templateUrl: function(elem, attr) { return "myTemplate-" + attr.type + ".html"; } }; });
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Demo for Directive</title> <script src="../angular-1.5.8.js"></script> <script src="modules.js"></script> </head> <body ng-app="mainModule"> <div ng-controller="MyController as mc"> <my-directive type="name"></my-directive> <my-directive type="job"></my-directive> <!-- <div my-directive type="name"></div> --> <!-- <div my-directive type="job"></div> --> </div> </body> </html>
<!-- myTemplate-name.html --> Name: {{mc.name}} <!-- myTemplate-job.html --> Job: {{mc.job}}
从上面的示例代码可以看出,template和templateUrl两个属性的值不只是接受字符串,还接受函数。要注意的是该函数默认带两个参数:
- 第一个参数代表当前的HTML DOM元素。
- 第二个参数代表当前HTML DOM元素的属性对象,在函数体内可以为该对象设置任何属性。
在上面的示例中,我们给代表当前DOM元素的属性对象设置了type属性,用于标识UI模板文件名称,这样我们就可以通过一个专有的模板指令来控制所有的UI模板文件了。
版权声明:本文为博主原创文章,未经博主允许不得转载。
: » AngularJS入门教程(四)指令详解和实践
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/251165.html