分享人:韩鹏
目录
1.背景介绍
2.知识剖析
3.常见问题
4.解决方案
5.编码实战
6.扩展思考
7.参考文献
8.更多讨论
directive的执行原理:
在AngularJS应用启动前,指令都以html文本的形式保存在文本编辑器中。当该应用启动后,会经过两个阶段,即编译阶段和链接阶段。之后,作用域(scope)会同html进行绑定,应用会对html中dom的操作进行实时响应。第一阶段是compile,第二阶段是link。
编译阶段: AngularJS会遍历整个html文档并根据JS中的指令定义来处理页面上声明的指令。换句话说, 在遍历dom时,所有的指令将被收集,但对dom树还没有进行数据绑定,此时对dom操作对性能影响很小。在编译阶段,同种 directive 在不同的 dom 节点出现一次,编译也会随之执行一次。然而,在这个阶段 scope 是无法访问到的。一个指令一旦编译完成,马上就可以通过编译函数对其进行访问。这个编译函数会返回一个模板函数,包含有完整的解析树。最后,模板函数被传递给编译后的dom树中每个指令定义的链接函数(link)。
链接阶段: Angular 会把所有 directive 的事件监听器注册到dom中并建立对 scope(作用域)的监听,并且把一个 scope 加到 directive 中。由于链接阶段是在编译阶段之后进行的,所以这时的scope是可以访问的。
compile函数负责对模板dom进行转换,它返回一个对象或者函数。compile本身相较于link函数不会那么频繁地使用。通常情况下,如果设置了compile函数,那就意味着可以在指令和实时数据被放到dom中之前对dom进行操作,在这个函数中进行例如添加或删除节点等dom操作都是安全的。
app.directive('myDirective', function() { return { compile: function(element, attrs, transclude){ var curEle = angular.element('id'); return function(scope, element, attrs) { //链接函数 }; } } });
参数解释:
element: 正在执行该指令的当前dom元素的jquery对象;
attrs: 正在执行该指令的当前dom元素的属性;
transclude: 模版替换之前的内容
link函数负责将作用域和dom进行链接,并对元素的注册事件进行监听。而在这个操作执行之前,可以手动操作dom。如果有了编译函数,它会返回一个链接函数,不需要另外定义。一般来说,都可按照以下代码来定义link函数(该函数的参数列表是固定的)。
app.directive('myDirective', function() { return { link: function(scope, element, attrs, controller) { //controller是require中指定的控制器,名字不能写错,不然对应不起来... } } });
参数解释:
scope:指令用来在其内部注册监听器的作用域。
element:element参数代表实例元素,指使用此指令的元素。在postLink函数中我们应该只操作此元素的子元素,因为子元素已经被链接过了。
attrs:attrs参数代表实例属性,是一个由定义在元素上的属性组成的标准化列表,可以在所有指令的链接函数间共享。会以JavaScript对象的形式进行传递。
controller:controller参数指向require选项定义的控制器。如果没有设置require选项,那么controller参数的值为undefined。
controller这里的属性值可以是一个字符串(控制器名称)或者函数(控制器内容)。如果属性值为字符串时,会以字符串为控制器的名字,查找在应用中已经注册过的控制器的构造函数。
app.directive('myDirective', function() { return { controller: function($scope, $element, $attrs, $transclude) { //controller逻辑内容 } or controller: 'MyController' } });
一般在控制器内部操作dom与AngularJS的风格不符,所以需要通过链接函数来实现这个功能。
自定义指令的控制器和link函数是可以进行互换的。控制器主要用来提供可在指令间复用的行为,但是链接函数只能在当前内部指令中定义行为,且无法在指令间复用。
作用:
compile:负责对模板dom进行转换;参考一:Angular自定义指令之compile, link, controller属性详解及实例演示
参考二:angular.js指令中的controller,compile,link函数有什么不同?
感谢大家观看
BY : 韩鹏