前几天在用textangular富文本编辑器插件时,将存储的文本及格式存储到数据库中,可是从后台接口中再向angular页面插入时却不能执行,即在Angular中操做DOM没有实现,后来查看了一下,操做DOM须要使用指令Directive封装DOM,这样尝试以后终于解决了问题,从而对指令也有了很大的了解,之后再操做DOm就要当心了html
如下是我查阅资料时看到的,感受so详细,解决了我不少issue,所以copy过来看看数据库
原文http://www.cnblogs.com/xuema/p/4350747.htmlapp
指令也是一种服务,只是这种服务的定义有几个特殊要求:编辑器
INSIDE:指令在注入器中的登记名称是:指令名+Directive。 例如,ng-app指令的服务名称是:"ngAppDirective"。函数
示例(http://www.dwz.cn/26R4S5中“使用指令封装DOM操做”第一页)定义一个简单的指令ez-hoverable,这个指令被限制只能 出如今属性的位置,每一个具备这个指令的HTML元素,将在鼠标移入 时以虚线边框突出显示。post
每一个指令定义的工厂函数,须要返回一个指令定义对象。指令定义对象就是 一个具备约定属性的JavaScript对象,编译器/$compile在编译时就根据这 个定义对象对指令进行展开。spa
指令定义对象的经常使用属性以下:插件
使用template指定的HTML标记替换指令内容(或指令自身)rest
用来限定指令在HTML模板中出现的位置。orm
使用这个属性指明template的替换方式。
scope属性为指令建立私有的做用域,这在建立可复用的Widget时很是有用。
link属性是一个函数,用来在指令中操做DOM树、实现数据绑定。
容许指令包含其余HTML元素,这一般用于实现一个容器类型的Widget。
最简单的指令只须要使用template属性进行模板替换就能够实现。
template指明一个HTML片断,能够用来:
示例(http://www.dwz.cn/26R4S5中“使用指令封装DOM操做”第三页)实现了一个ezCustomer指令,这个指令只是简单的使用template指定的 模板替换ez-customer的内容:
restict属性能够是EACM这四个字母的任意组合,用来限定指令的应用场景。 若是不指定这个属性,默认状况下,指令将仅容许被用做元素名和属性名:
咱们对以前的示例,增长一个restrict属性,限制这个只能做为元素名使用。 代码已经预置到右边,你能够看到,如今惟一合法的方式是使用以下方式应用指令:
考查编译后的DOM结构,你会发现ez-customer这个”伪“HTML标签还被保留着,这有时让完美 主义者有点闹心:
咱们但愿使用template完整地替换原始的DOM对象,而不是填充其内容,replace 属性负责这件事。
replace属性指明使用template时,如何替换指令元素:
示例(http://www.dwz.cn/26R4S5中“使用指令封装DOM操做”第五页)增长了replace属性,值为true意味着这个指令要求编译器使用template 替换原始的DOM元素:
你可能注意到模板的内容稍微修改了一下,这是由于replace为true时,要求模板有 一个根节点。
默认状况下,指令没有本身的scope对象,换句话说,它使用所在DOM对象对应的scope对象。
那么问题来了,若是一个指令在同一个scope内出现屡次,会怎样?
没错,因为两个ez-customer指令都处在ezCtrl开辟的做用域内,因此两个指令绑定到了一样的 数据模型上,获得的是重复的结果。
显然,咱们能够将每一个ez-customer指令置于不一样的做用域下,这意味着咱们给每一个ez-customer 一个不一样的控制器:
看起来很怪异,对吗?
经过设置scope属性,指令的每一个实例都将得到一个隔离的本地做用域:
在上面的例子中,咱们在本地scope上定义了两个属性:name和address,这样在 模板中就可使用name和address了。
你应该已经注意到,name属性的值以前有一个@符号,这是一个约定好的标记,它 告诉编译器,本地scope上的name值须要从应用这个指令的DOM元素的name属性值 读取,若是DOM元素的name属性值变了,那么本地scope上的name值也会变化。
一样,address属性以前的=符号也是一个约定好的标记,它告诉编译器,本地scope 上的address属性值和DOM元素的address属性值指定的外部scope对象上的模型须要 创建双向链接:外部scope上模型的变化会改变本地scope上的address属性,本地 scope上address属性的变化也会改变外部scope上模型的变化。
有点绕,上个图:
从图中能够看出:
若是须要在指令中操做DOM,咱们须要在对象中定义link属性,link函数的定义以下:
注意link函数的参数,AngularJS在编译时负责传入正确的值:
指令对应的scope对象。若是指令没有定义本身的本地做用域,那么传入的就是外部的 做用域对象。
指令所在DOM对象的jqLite封装。若是使用了template属性,那么iElement对应 变换后的DOM对象的jqLite封装。
指令所在DOM对象的属性集。这是一个Hash对象,每一个键是驼峰规范化后 的属性名。
后两个参数咱们先略过。
示例(http://www.dwz.cn/26R4S5中“使用指令封装DOM操做”第八页)中,咱们实现了一个能够指定显示格式的小时钟指令:ezCurrentTime。和原来同样, 咱们在link函数中启动定时器,并在定时器中更新DOM。有几点解释下:
有些指令须要可以包含其余未知的元素。好比咱们定义一个指令ez-dialog,用来 封装对话框的样式和行为,它应当容许在使用期(也就是在界面模板文件里)才指 定其内容:
transclude属性能够告诉编译器,利用所在DOM元素的内容,替换template中包含 ng-transclude指令的元素的内容:
从上图中能够看到,使用transclude有两个要点:
右边嵌入了ez-dialog的实现实例(http://www.dwz.cn/26R4S5中“使用指令封装DOM操做”第九页)。