AngularJS 指令
2015-10-09 17:36
826 查看
指令
对于指令,可以把它简单的理解成在特定DOM元素上运行的函数,指令可以扩展这个元素的功能。指令格式
angular.application('myApp', []) .directive('myDirective', function() { // 一个指令定义对象 return { // 通过设置项来定义指令,在这里进行覆写 }; });
当AngularJS启动应用时,它会把第一个参数当作一个字符串,并以此字符串为名来注册第二个参数返回的对象。AngularJS编译器会解析主HTML的DOM中的元素、属性、注释和CSS类名中使用了这个名字的地方,并在这些地方引用对应的指令。当它找到某个已知的指令时,就会在页面中插入指令所对应的DOM元素。
指令的工厂函数只会在编译器第一次匹配到这个指令时调用一次。和controller函数类似,
$injetor.invoke可以被用来调用指令的工厂函数。
当AngularJS在DOM中遇到具名的指令时,会去匹配已经注册过的指令,并通过名字在注册过的对象中查找。此时,就开始了一个指令的生命周期,指令的生命周期开始于
$compile方法并结束于
$link方法。
指令全部设置选项
angular.module('myApp', []) .directive('myDirective', function() { return { restrict: String, priority: Number, terminal: Boolean, template: String or Template Function: function(tElement, tAttrs) {...}, templateUrl: String, replace: Boolean, scope: Boolean or Object, transclude: Boolean or String, controller: String or function(scope, element, attrs, transclude, otherInjectables) { ... }, controllerAs: String, require: String, link: function(scope, iElement, iAttrs) { ... }, compile: // 返回一个对象或连接函数,如下所示: function(tElement, tAttrs, transclude) { return { pre: function(scope, iElement, iAttrs, controller) { ... }, post: function(scope, iElement, iAttrs, controller) { ... } } // 或者 return function postLink(...) { ... } } }; });
[b]restrict(字符串)[/b]
EACM的子集的字符串,它限制directive为指定的声明方式。如果省略的话,directive将仅仅允许通过属性声明:
类型 | 描述 | 示例 |
---|---|---|
E | 元素名称 | <my-directive></my-directive> |
A | 属性 | <div my-directive="exp"></div> |
C | 样式 | <div class="my-directive:exp;"></div> |
M | 注释 | <!-- directive: my-directive exp --> |
优先级参数可以被设置为一个数值。大多数指令会忽略这个参数,使用默认值0,但也有些场景设置高优先级是非常重要甚至是必须的。例如,ngRepeat将这个参数设置为1000,这样就可以保证在同一元素上,它总是在其他指令之前被调用。如果一个元素上具有两个优先级相同的指令,声明在前面的那个会被优先调用。
示例:
ngRepeat在遍历元素的过程中,我们需要Angular首先生成模板元素的拷贝,然后再应用其他指令。
如果不这样做,其他指令就会被应用到标准模板元素(未拷贝前)上,而不会应用到需要的遍历元素上。
[b]termina(布尔型)[/b]
高优先级指令会先执行。这个参数如果设置为”true”,则表示当前的priority将会成为最后一组执行的指令。任何directive与当前的优先级相同的话,他们依然会执行,但顺序是不确定的(虽然顺序不确定,但基本上与priority的顺序一致)。当前优先级执行完毕后,更低优先级的将不会再执行。
[b]template(字符串或函数)[/b]
如果replace 为true,则将模版内容替换当前的HTML元素,并将原来元素的属性、class一并迁移;如果为false,则将模版元素当作当前元素的子元素处理。
[b]templateUrl[/b]
与template基本一致,但模版通过指定的url进行加载。因为模版加载是异步的,所以compilation、linking都会暂停,等待加载完毕后再执行。
[b]replace[/b]
如果设置为true,那么模板将会替换当前元素(并且应用原元素的所有属性),否则,将模板作为子元素添加到当前元素中。(注:为true时,模版必须有一个根节点)
[b]transclude[/b]
通过transclude属性将内容插入新的模板。当此属性设置为true的时候,指令会删掉原来的内容,使你的模板可以用
ng-transclusde指令进行重新插入。
app.directive('hello', function() { return { template: '<div>Hi there <span ng-transclude></span></div>', transclude: true }; });
1.使用以下内容运行它:
<div hello>Bob</div>
结果:
<div hello> <div>Hi there <span ng-transclude><span class="ng-scope">Bob</span></span> </div> </div>
2.使用以下内容运行它:
<div hello><p>Bob</p></div>
结果:
<div hello> <div>Hi there <span ng-transclude><p class="ng-scope">Bob</p></span> </div> </div>
[b]controller[/b]
创建一个控制器,它会暴露一个API,利用这个API可以在多个指令间进行通信。(见*《用AngularJS开发下一代Web应用》*P135)
[b]require[/b]
要求必须存在另一个指令,当前指令才能正确运行,例(
^?myDirective): 在当前指令中传入另一个含控制器(为了暴露API)的指令,进行多指令通信。
类型 | 描述 | 示例 |
---|---|---|
? | 默认Angular未找到控制器会抛出异常,?表示该控制器是可选的,没找到,不抛出异常。 | ?myDirective |
^ | 默认Angular从同一元素上的命名指令中获取控制器。^表示允许遍历DOM树查找指令,获取controller。 | ^myDirective |
用来对模板自身进行转换,仅仅在编译阶段执行一次。
//compile函数会接收模板元素及其属性列表,所以函数形参带t前缀。 function compile ( tElement, tAttrs, transclude) { … }
[b]link[/b]
负责在模型和视图之间进行动态关联,link函数会执行很多次——对于指令的每个实例,link函数都会执行一次。
//link函数会接受视图实例对象,视图实例是使用模板创建的,所以函数形参带i前缀。 function link( scope, iElement, iAttrs, controller) { … }
注意 post-link function: 仅仅在这里执行DOM转换是安全的。
[b]scope[/b]
类型 | 取值 |
---|---|
现有scope | false(默认值) |
新scope | true |
独立scope | {/* 属性名和绑定风格 */} |
@或@attr - 建立一个local scope property到DOM属性的绑定。因为属性值总是String类型,所以这个值总是返回一个字符串。如果没有通过@attr指定属性名称,那么本地名称将与DOM属性的名称一致。例如
<widget my-attr="hello {{name}}">,widget的scope定义为:
{localName:'@myAttr'}。那么,widget scope property的localName会映射出”hello {{name}}”转换后的真实值。name属性值改变后,widget scope的localName属性也会相应地改变(仅仅单向,与下面的”=”不同)。name属性是在父scope读取的(不是组件scope)
=或=attr - 在本地scope属性与parent scope属性之间设置双向的绑定。如果没有指定attr名称,那么本地名称将与属性名称一致。例如
<widget my-attr="parentModel">,widget定义的scope为:
{localModel:'=myAttr'},那么widget scope property “localModel”将会映射父scope的“parentModel”。如果parentModel发生任何改变,localModel也会发生改变,反之亦然。(双向绑定)
&或&attr - 提供一个在父scope上下文中执行一个表达式的途径。如果没有指定attr的名称,那么local name将与属性名称一致。例如
<widget my-attr="changeAttr()">,widget的scope定义为:
{localFn:'&myAttr'},那么isolate scope property “localFn”会指向changeAttr的function。
学习链接
示例
<!DOCTYPE html> <html ng-app="ZippyModule"> <head> <title>ZippyModule</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"> <style type="text/css"> .zippy { border: 1px solid black; display: inline-block; width: 250px; } .zippy.opened > .title:before { content: '▼ '; } .zippy.opened > .body { display: block; } .zippy.closed > .title:before { content: '► '; } .zippy.closed > .body { display: none; } .zippy > .title { background-color: black; color: white; padding: .1em .3em; cursor: pointer; } .zippy > .body { padding: .1em .3em; } </style> <script src="scripts/vendor/angular/angular.js" type="text/javascript"></script> </head> <body> <div ng-controller="MyCtrl"> Title: <input ng-model="title"><br/> Text: <textarea ng-model="text" ></textarea> <hr/> <div class="zippy" zippy-title="Details:{{title}}...">{{text}}</div> </div> <script type="text/javascript"> var myModule = angular.module("ZippyModule", []); myModule.controller("MyCtrl", function ($scope) { $scope.title = "这里是标题"; $scope.text = "这里是内容哇。。。"; }); myModule.directive('zippy', function () { return { template: '<div>' + ' <div class="title">{{title}}</div>' + ' <div class="body" ng-transclude></div>' + '</div>', replace: true, transclude: true, restrict: 'C', scope: { title:"@zippyTitle" }, link: function(scope, element, attrs) { var title = angular.element(element.children()[0]); opened = false; title.bind("click", toogle); element.addClass("closed"); function toogle() { opened = !opened; element.removeClass(opened ? "closed" : "opened"); element.addClass(opened ? "opened" : "closed"); } } }; }); </script> </body> </html>
推荐阅读: 《AngularJS权威教程》 & Developer Guide/Directives & 借眼观世界 & 好用插件 & 学习资源
相关文章推荐
- angularjs基础—scope
- AngularJs之ng-repeat的用法
- angularjs操作indexeddb
- AngularJS 表格
- Angularjs基础知识
- angularJs自定义指令用到的属性和方法
- angularjs学习笔记—事件指令
- angularjs学习
- AngularJS Filters
- AngularJS 控制器
- 集DDD,TDD,SOLID,MVVM,DI,EF,Angularjs等于一身的.NET(C#)开源可扩展电商系统–Virto Commerce
- angular+rest+auth
- 关于angularjS与jQuery框架的那些事
- AngularJS的优缺点
- 认识AngularJS
- AngularJS理论基础
- angularJs基础
- JQuery、AngularJs动态加载其他页面
- Angularjs的核心概念
- angularjs 实现 文件拖拽,缩略图显示