Angular开发者手册重点翻译之指令(一)

创建自定义的指令

这个文章将解释什么需要在自己的angularjs应用中创建自己的指令,以及如何实现它。

什么是指令

在高的层面上讲,指令是DOM元素中的标记(例如一个属性,一个节点名,注释或者CSS类),它告诉angularjs编译器去给这个元素附加一个指令的行为或者转换DOM元素和它的子元素。

Angularjs拥有一些内建的指令,像ngBind、ngModel和ngClass。非常类似于你创建自己的controller和service,你可以创建你自己的指令个angularjs使用,党angular初始化启动你的应用程序,html编译器将遍历你的DOM元素并且去匹配指令。

匹配指令

在你可以编写指令之前,你需要知道当你使用一个给定的指令的时候,angularjs的html编译器是怎样工作的.

在下面的例子里,我们说<input>元素匹配了ngModel指令:

<input&nbsp;ng-model="foo">
下面的例子也同样匹配ngModel指令:
<input&nbsp;data-ng:model="foo">

Angular规范是一个元素标签和属性名去决定哪个元素匹配哪个指令,我们通常使用大小写敏感的驼峰式规范化命名应用指令。可是因为HTML是大小写不敏感的,所以我们在DOM中使用小写的方式去引用指令,通常在DOM元素上使用短划线分隔的属性。

规范化的形式如下所示:

1:去除元素或者属性以x-和data-的开头。

2:使用:/_/-分隔驼峰式的命名。

例如,以下的格式都是等价的并且匹配ngBind指令:

<div&nbsp;ng-controller="Controller">
  Hello <input&nbsp;ng-model='name'> <hr/>
  <span&nbsp;ng-bind="name"></span> <br/>
  <span&nbsp;ng:bind="name"></span> <br/>
  <span&nbsp;ng_bind="name"></span> <br/>
  <span&nbsp;data-ng-bind="name"></span> <br/>
  <span&nbsp;x-ng-bind="name"></span> <br/>
</div>

最佳实践:推荐使用短划线间隔的格式(比如ngBind指令使用ng-bind),假如你想使用一个HTML验证工具,你可以换为使用data-前缀的样式(比如ngBind指令使用data-ng-bind)。其他的样式,在一些遗留的因素上也是可接受的,但是我们建议你避免使用它们

所有Angular提供的指令匹配属性名、标签名、注释或者类名,下面演示了一个指令可以被引用的几种方式:

<my-dir></my-dir>
<span&nbsp;my-dir="exp"></span>
<!-- directive: my-dir exp -->
<span&nbsp;class="my-dir: exp;"></span>

最佳实践:对比注释和类型,我们更多的倾向于使用标签名和属性,这样可以更容易地确定哪个指令是元素需要去匹配的。

最佳实践:注释形的指令通常用于DOM API不可以跨越多个元素去创建指令的限制(比如在table元素内部),AngularJS 1.2加入了ng-repeat-start和ng-repeat-end作为这个问题的一个更好的解决方案,开发人员被鼓励使用这种方式来替换注释形的指令。

文本和属性绑定

在编译工作阶段,编译器使用$interpolate服务匹配文本和属性,它将发现他们是否包含嵌入的表达式。这些表达式将被注册为watchs,并且作为一个通常的生命周期的一部分被更新,下面是一个interpolation的示例:

<a&nbsp;ng-href="img/{{username}}.jpg">Hello {{username}}!</a>

ngAttr属性绑定

浏览器对属性是否合法经常是挑刺的,例如,考虑一下这个例子:

<svg>
  <circle&nbsp;cx="{{cx}}"></circle>
</svg>

我们期望Angular可以去绑定它,但是当我们查看控制台,我们将会看到一些这样的信息

Error: Invalid value for attribute cx="{{cx}}"

因为SVG DOM API是严谨话的,你不可以简单的写cx="{{cx}}"这样的属性。但是你可以使用ng-attr-cx来绕过这个问题,加入有一个拥有绑定的属性是拥有ngAttr前缀的,在绑定阶段,它将会被应用到相应的无前缀的属性上,这样就允许你去绑定你想要的属性,否则你只能看着它被浏览器处理掉,当使用ngAttr的时候,$interpolate的allOrNothing标识被使用,所以假如任何表达式返回的是undefined,这个属性将会被移除而不是添加到元素上。例如,我们可以像这样修复上文中的问题

<svg>
  <circle&nbsp;ng-attr-cx="{{cx}}"></circle>
</svg>

假如想要去使用一个驼峰式属性名,像viewBox,可以使用下划线去指示属性去绑定到一个实际的驼峰属性上。例如下文中绑定一个viewBox,我们可以这样写:

<svg&nbsp;ng-attr-view_box="{{viewBox}}">
</svg>

创建指令

首先让我们谈谈注册指令的API,与controller相似,指令是注册在module上的,想要注册它,你可以使用module.directive   API,module.directive需要一个规范化的指令名跟随着一个工厂方法,这个工厂方法需要返回一个包含不同选项来告诉$compile指令在被匹配的时候应该怎样去表现的对象。

这个工厂方法只会被在编译器匹配到指令的第一次的时候调用一次,你可以在这个时机执行任何的初始化工作,这个方法需要被$compile.invoke调用使得它可以像controller一样是可注入的。

最佳实践:推荐使用定义对象而不是返回一个方法。

我们将会使用一些指令的通常示例,然后进行深入的探讨不同的选项和编译过程。

最佳实践:为了避免与将来的标准冲突,最好为你自己的指令加一个前缀,比如,加入你想创建一个carousel指令,如果HTML7包含了一个这样的元素,这就会有问题了,两个或者三个字母的前缀就会使它工作的很好,同样的,不要给自己的指令加上ng或者可能会和未来版本的angular引起冲突的前缀。

最新文章

  1. sipex3232上电发送输入端拉低问题
  2. LVM &#39;Can’t open /dev/sdb1 exclusively. Mounted filesystem?&#39; Problem
  3. jdbc的实例应用:增删查改实现
  4. laravel增删改查
  5. NGUI 修改Shader支持灰色滤镜
  6. JS 之DOM对象(2)
  7. HTML-Canvas03
  8. Javascript链式调用案例
  9. db link的查看创建与删除
  10. 201521123028 《Java程序设计》 第9周学习总结
  11. percona_xtrabackup
  12. salt基本使用之二(2)
  13. codeforces_Codeforces Round #541 (Div. 2)_abc
  14. 【原创】大数据基础之Ambari(1)简介、编译安装、使用
  15. Redis详解(一)冰叔带你了解Redis
  16. (转)ElasticSearch学习
  17. iOS-绘图之CoreGraphics框架
  18. 【WinRT】多语言化应用程序名称
  19. MongoDB 分页
  20. JS-类型相关

热门文章

  1. 于linux已安装moodle
  2. android键盘锁定问题
  3. UVa 10012 - How Big Is It? 堆球问题 全排列+坐标模拟 数据
  4. UVa 10190 - Divide, But Not Quite Conquer!
  5. Qt5该插件机制(4)--QtMeta信息窗口小部件metaData
  6. tc-SRM-626-DIV1-250
  7. 记录这一刻:百度搜索结果“文件格式:-HTML文本”
  8. IT互联网行业中相关职能的缩写
  9. enq: TX - row lock contention 参数P1,P2,P3说明
  10. sql小总结2