今天就要介绍angularjs最为强大的一个功能了,那就是指令系统。我们在做项目的时候,会发现很多前端的东西几乎都是差不多的,你比如说表格,表单,开关,上传下载等功能在形式上很想,只是内容可能有些差别,这时我们就不需要每个页面用到的时候,都去定义一遍。这时我们就需要将这些东西统一起来,定义一个共同的模板来让不同的页面进行引用,这就是angularjs的指令系统所能达到的功能。
简单的说,angularjs指令系统包含这么两部分:
1.angularjs自带指令
指令是我们用来扩展浏览器能力的技术之一。在DOM编译期间,和HTML元素关联着的指令会被检测到,并且被
检测到,并且被执行,这使得指令可以为DOM指定行为,或者改变它。AngularJS有一套完整的、可扩展的、用来帮助web应用开发的指令集,它使得HTML可以转变成“特定领域语言(DSL)”。
angular在编译期间,编译器会用$interpolate服务去检查文本中是否嵌入了表达式。这个表达式会被当成一个监视器一样注册,并且作为$digest循环中的一部分,它会自动更新。
angular在编译期间,编译器会用$interpolate服务去检查文本中是否嵌入了表达式。这个表达式会被当成一个监视器一样注册,并且作为$digest循环中的一部分,它会自动更新。
angularjs的强大之处除了定义了一些自身的指令系统来把一些公用的功能封装来提供给大家使用,而且还支持读者自定义适合自己项目需求的一些指令系统。angularjs定义了自定义指令格式,只要按照格式,就可以定义自己的指令,来迎合需求。先来看一个简单的例子:
图中展示了使用指令的两种方式即作为元素和属性。作为元素可以可<div>,<p>等DOM元素一样,能被浏览器识别<hello></hello>,同样也可以作为DOM元素的某个属性<div hello ="youhello"></div>这么使用。
我们再看看他为什么在页面加载完毕之后hello的内容发生了变化?我们在APP中定义了一个directive,这个directive是angularjs提供的指令,使用它可以定义自己的指令格式,在编译阶段会将这段指令解析成它所对应的html片段即<h3>Hello,Directive</h3>并将<hello><hello>替换掉。我们再想想如果这个template模板换成一个封装的表格,那么在其他的页面也只需要将引用到这个指令,这个简简单单的一行代码,就会实际输出一个表格,想想是不是很激动。
接着我们就来介绍一下angularjs提供哪些自带的指令(列举了常用的一些指令):
- ng-init
- ng-app
- ng-controller
- ng-form
- ng-disabled
- ng-readonly
- ng-checked
- ng-selected
- ng-show/ng-hidden
- ng-change
- ng-bind
- ng-cloak
- ng-if
- ng-switch
- ng-repeat
- ng-href
- ng-src
- ng-class
- ng-model
1.1 ng-init
指令说明:
该指令被调用时会初始化内部作用域,应用场景比较少
Demo:
<div ng-init="job='fighter'"> I am a/an {{job}} </div>
1.2 ng-app
指令说明:
指令启动一个AngularJS应用。它定义根元素。它会自动初始化或启动加载包含AngularJS
应用程序的Web页面的应用程序。它也被用来加载各种AngularJS模块AngularJS应用。在下面的例子中,
我们定义默认AngularJS应用使用div元素的ng-app属性。
Demo:
html
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body ng-controller="mainController"> {{name}} </body> </html>
js
angular.module("main",[])
.controller("mainController",["$scope",function ($scope) {
$scope.name = "angular";
}])
上面定义了一个简单的APP应用,同时定义了一个controller。
1.3 ng-controller
说明:
该指令用于装载在页面某个DOM元素上,以指定该元素的作用域。即该controller定义的数据只能通过数据绑定到该元素对应的作用域中。
Demo:
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body > <div ng-controller="mainController1"> {{name}}---->aq </div> <div ng-controller="mainController2"></div> {{name}}---->lily </body> </html>
angular.module("main",[]) .controller("mainController1",function ($scope) { $scope.name = "aq"; }]) .controller("mainController2",function ($scope) { $scope.name = "lily"; }])
1.4 ng-form
说明:
表单指令,应用场景较少,一般用于多表单验证
Demo:
<form name="mainForm" novalidate> <div ng-form="form1"> 姓名:<input type="text" ng-required="true" ng-model="name"/> 证件号码:<input type="number" ng-minLength="15" ng-maxLength="18" ng-required="true" ng-model="idnu"/> </div> <div ng-form="form2"> 监护人姓名:<input type="text" ng-required="true" ng-model="gname"/> 监护人证件号码:<input type="number" ng-minLength="15" ng-maxLength="18" ng-required="true" ng-model="gidnum"/> </div> <button ng-disabled="form1.$invalid && form2.$invalid">submit all</button> </form> <form name="mainForm" role="form" novalidate> <div> 监护人姓名:<input type="text" ng-required="true" ng-model="gname"/> 监护人证件号码:<input type="number" ng-minLength="15" ng-maxLength="18" ng-required="true" ng-model="gidnum"/> </div> <button ng-disabled="mainForm.$invalid">submit all</button> </form>
1.5 ng-disabled
说明:
该指令用于指定某元素是否可用,常用值true/false
Demo:
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body> <div ng-controller="mainController"> <input ng-disabled="isUsed" type="button" value="test"> </div> </body> </html>
angular.module("main",function ($scope) { $scope.isUsed = true; }]);
当isUsed取值为true,该按钮可以点击,否则不可点击,常用语控制form表单的提交按钮,如果所有表单项都符合规则,则允许用户点击提交按钮,否则不允许。
1.6 ng-readonly
说明:
指定元素是否只读
Demo:
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body> <div ng-controller="mainController"> <input ng-disabled="isUsed" type="button" value="test"> <input ng-readonly="isReadonly" type="text" value="test"> </div> </body> </html>
angular.module("main",function ($scope) { $scope.isUsed = true; $scope.isReadonly = true; }]);
1.7 ng-checked
说明:
Demo:
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body> <div ng-controller="mainController"> <input ng-checked="checkedItem" type="checkBox" value="test"> </div> </body> </html>
angular.module("main",function ($scope) { $scope.checkedItem = true; }]);
1.8 ng-selected
说明:
该指令作用域页面元素input[type=select],表明某option元素被选中,常用值true,false
Demo:
@H_301_479@<!DOCTYPE html>
<html ng-app="main">
<head lang="en">
<Meta charset="UTF-8">
<title></title>
</head>
<body>
<div ng-controller="mainController">
<select>
<option>select one</option>
<option>select two</option>
<option ng-selected="selectedItem">select three</option>
</select>
</div>
</body>
</html>
angular.module("main",function ($scope) { $scope.selectedItem = true; }]);
1.9 ng-show/ng-hidden
说明:
Demo:
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body> <div ng-controller="mainController"> <div ng-show="showItem"> you can show me or hidden me </div> <div ng-show="1==1"> you can show me or hidden me </div> </div> </body> </html>
angular.module("main",function ($scope) { $scope.showItem = true; }]);
以上这几个指令是true/false的取值,可以指定一个对象,也可以使用表达式来控制。
1.10 ng-change
说明:
Demo:
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body> <div ng-controller="mainController"> <input type="text" value="you change my value" onchange="changeValue()"> </div> </body> </html>
angular.module("main",function ($scope) { $scope.changeValue = function () { console.info("you change my value"); } }]);
当输入框的值不断发生变化时,会在浏览器控制台输出打印信息。
1.11 ng-bind
说明:
Demo:
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body> <div ng-controller="mainController"> <input type="text" ng-bind="detailInformation"> </div> </body> </html>
angular.module("main",function ($scope) { $scope.detailInformation = "the detail information"; }]);
1.12 ng-cloak
说明:
ng-cloak 指令用于在 AngularJS 应用在加载时防止 AngularJS 代码未加载完而出现的问题。angularjs在加载的时候,文档可能会由于angularjs代码未加载完而显示angularjs代码,进而出现闪烁效果,该指令会避免出现这种问题。
Demo:
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body> <div ng-controller="mainController"> <div ng-cloak></div> </div> </body> </html>
1.13 ng-if
说明:
该指令作用于页面DOM元素,可以控制DOM元素的显示与隐藏,与ng-show/ng-hidden不同的是,如果在页面加载的时候该指令被赋值为false,即不显示该DOM元素那么在f12模式下是看不到该元素的,即该元素被DOM remove掉了。当该指令为true时,DOM元素则会加载该元素,会显示这个元素。通常在form表单验证时会碰到这个问题。如果指令修饰的元素有校验规则,那么你使用ng-show的时候即使隐藏掉该元素,他还是存在在DOM中的,所以表单校验还是回去检测并校验该表单项,而使用ng-if就不一样,该元素会完全消失就像不存在一样,表单校验也会忽略该元素。
Demo:
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body> <div ng-controller="mainController"> <div ng-if="true"> 我是存在的,也可以是不存在的 </div> </div> </body> </html>
1.14 ng-switch
说明:
根据表达式的值显示或者隐藏对应的部分,子元素使用ng-switch-when,匹配成功不隐藏,匹配不成功隐藏
Demo:
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body> <div ng-controller="mainController"> <element name="" ng-switch="1"> <element name="" ng-witch-when="1"></element> <element name="" ng-witch-when="2"></element> <element name="" ng-witch-when="3"></element> </element> </div> </body> </html>
1.15 ng-repeat
说明:
用于遍历集合,并支持排序,一般用于select集合,table集合等
Demo:
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body> <div ng-controller="mainController"> <table class="table-condensed" style="width:100%;"> <thead> <tr> <td style="width: 50%" ng-click="col='ssid';desc=!desc"> {{"WlAN Name"|translate}} </td> </tr> </thead> </table> <table style="width: 100%;table-layout:fixed;" id="wlan_view_table"> <tbody> <tr ng-repeat="item in wlans | orderBy:col:desc" monitor-high-light="wlan"> <td style="padding-left:10px;width:50%;"> {{item.ssid}}</td> </tr> </tbody> </table> </div> </body> </html>之前的文章讲到ng-repeat的问题,注意的一点就是使用ng-repeat的时候,会对遍历出来的每一个元素重新定义一个作用域,这使得原本定义在$scope中的数据不再作用域中,关于如何规避,在另一篇中讲到。
1.16 ng-href
说明:
Demo:
<div ng-init="myVar = 'http://www.runoob.com'"> <h1>菜鸟教程</h1> <p>访问 <a ng-href="{{myVar}}">{{myVar}}</a> 学习!</p> </div>
1.17 ng-src
说明:该指令作用于页面元素,指向某个资源同src
Demo:
<img src="{{mysrc}}">
angular.module("main",function ($scope) { $scope.mysrc = "/test/test.png" }]);
1.18 ng-class
说明:
作用于页面元素,指定样式
Demo:
<div ng-controller="mainController"> <button ng-click="getCurrentSecond()">Get Time!</button> <p ng-class="{red: x%2==0,blue: x%2!=0}">Number is: {{ x }}</p> </div>
angular.module("main",function ($scope) { $scope.getCurrentSecond = function () { $scope.x = new Date().getSeconds(); }; }]);
1.19 ng-model
Demo:
<div ng-controller="mainController"> <input type="text" ng-model="inputValue"> </div>
angular.module("main",function ($scope) { $scope.inputValue = "value"; }]);
2.自定义指令
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body> <div ng-controller="mainController"> <my-directive-name></my-directive-name> 解析之后会变成这种格式 <p>你好,我是自定义指令</p> </div> </div> </body> </html>
angular.module("main",function ($scope) { $scope.inputValue = "value"; }]) .directive("myDirectiveName",function () { return { restrict:"A",replace:"true",template:"<p>你好,我是自定义指令</p>" } });上面就是一个简单的自定义指令,我们来看看它所代表的都是什么意思。
2.1 Template
说明:
string类型时,返回一段HTML代码段
function(tElement,tAttr)类型时,返回元素及其属性组合
<!DOCTYPE html> <html ng-app="main"> <head lang="en"> <Meta charset="UTF-8"> <title></title> </head> <body> <div ng-controller="mainController"> <hello-world></hello-world> <hello-world2 title='i am second directive'></hello-world2> </div> </div> </body> </html>
angular.module("main",function ($scope) { $scope.inputValue = "value"; }]) .directive('helloWorld',function () { return { restrict: 'E',template: '<div><h1>Hi i am first directive</h1></div>',replace: true }; }).directive("helloWorld2",function () { return { restrict: 'EAC',template: function (tElement,tAttrs) { var _html = ''; _html += '<div>' + 'hello ' + tAttrs.title + '</div>'; return _html; } }; }); ;
2.2 TemplateUrl
说明:
指向一个url模板路径
Demo:
下面是个url路径对应的html页面
<form role="form"> <div class="form-group"> <label>userName:</label> <input type="text" ng-model="user.userName"> </div> <div class="form-group"> <label>password:</label> <input type="text" ng-model="user.userName"> </div> <div class="form-group"> <label>repeat password:</label> <input type="text" ng-model="user.userName"> </div> </form>
angular.module("main",function ($scope) { $scope.inputValue = "value"; }]) .directive('testModel',function () { return {restrict: 'E',templateUrl: '/www/static/test.html',replace: true}; })
<test-model></test-model>
2.3Restrict
Restrict:
A(代表属性) <div my-directive="expression"></div>
E(代表元素) <my-directive></my-directive>
C(代表类) <div class="my-directive:expression;"></div>
M(代表注释) <--directive:my-directive expression-->
A(代表属性) <div my-directive="expression"></div>
E(代表元素) <my-directive></my-directive>
C(代表类) <div class="my-directive:expression;"></div>
M(代表注释) <--directive:my-directive expression-->
2.4 Transclude
说明:
"嵌入",指在指定的位置插入或者追加模板,默认值为true/false,不会替换原有元素下的子元素,会在该元素子元素的基础上追加一个模板。
Demo:
angular.module("main",function ($scope) {
$scope.inputValue = "value";
}])
.directive('myDirective',function () {
return {
restrict: 'EA',scope: {title: '@',content: '='},transclude: true,template: '<h2 class="header">{{ title }}</h2><span class="content" ng-transclude></span>'
};
})
<div ng-controller="mainController">
<div my-Directive>
<span>我不会被替换掉哦</span>
</div>
</div>
他不会将<span>这段代码给替换掉,而会在span后追加你定义的模板。
2.5 replace
说明: