大家好,我是IT修真院深圳分院第04期学员,一枚正直善良的web程序员。
今天给大家分享一下,修真院官网 js任务中可能会使用到的知识点:
angular js自定义指令 directive 如何使用?
1.背景介绍
指令定义
对于指令,可以把它简单的理解成在特定DOM元素上运行的函数,指令可以扩展这个元素
的功能。
例如, ng-click 可以让一个元素能够监听 click 事件,并在接收到事件的时候执行AngularJS表
达式。正是指令使得AngularJS这个框架变得强大,并且正如所见,我们可以自己创造新的指令。
AngularJS应用的模块中有很多方法可以使用,其中 directive( )这个模块是用来定义指令的。
2.知识剖析
directive( )模块解析
directive( )方法可以接受两个参数:
1. name (字符串)
指令的名字,用来在视图中引用特定的指令。
2. factory_function (函数)
这个函数返回一个对象,其中定义了指令的全部行为。 $compile 服务利用这个方法返回的对
象,在DOM调用指令时来构造指令的行为。
当AngularJS启动应用时,它会把第一个参数当作一个字符串,并以此字符串为名来注册第
二个参数返回的对象。AngularJS编译器会解析主HTML的DOM中的元素、属性、注释和CSS类名
中使用了这个名字的地方,并在这些地方引用对应的指令。当它找到某个已知的指令时,就会在
页面中插入指令所对应的DOM元素。
tips:为了避免与未来的HTML标准冲突,给自定义的指令加入前缀来代表自定义的
命名空间。AngularJS本身已经使用了 ng- 前缀,所以可以选择除此以外的名字。
在例子中我们使用 my- 前缀(比如 my-derictive )。
当模板在上面代码中返回时,你可以把以下的属性列表应用于指令定义返回的对象
restrict(字符串)
restrict 是一个可选的参数。它告诉AngularJS这个指令在DOM中可以何种形式被声明。默
认AngularJS认为 restrict 的值是 A ,即以属性的形式来进行声明。
可选值如下:
当模板在上面代码中返回时,你可以把以下的属性列表应用于指令定义返回的对象
restrict(字符串)
restrict 是一个可选的参数。它告诉AngularJS这个指令在DOM中可以何种形式被声明。默
认AngularJS认为 restrict 的值是 A ,即以属性的形式来进行声明。
可选值如下:
template (字符串或函数)
template 参数是可选的,必须被设置为以下两种形式之一:
一段HTML文本;
一个可以接受两个参数的函数,参数为 tElement 和 tAttrs ,并返回一个代表模板的字符
串。 tElement 和 tAttrs 中的 t 代表 template ,是相对于 instance 的。在讨论链接和编译
设置时会详细介绍,模板元素或属性与实例元素或属性之间的区别。
AngularJS会同处理HTML一样处理模板字符串。模板中可以通过大括号标记来访问作用域,
例如 {{ expression }} 。
templateUrl (字符串或函数)
templateUrl 是可选的参数,可以是以下类型:
一个代表外部HTML文件路径的字符串;
一个可以接受两个参数的函数,参数为 tElement 和 tAttrs ,并返回一个外部HTML文件
路径的字符串。
无论哪种方式,模板的URL都将通过AngularJS内置的安全层,特别是 $getTrusted
ResourceUrl ,这样可以保护模板不会被不信任的源加载。
transclude
transclude 是一个可选的参数。如果设置了,其值必须为 true ,它的默认值是 false 。
嵌入有时被认为是一个高级主题,但某些情况下它与我们刚刚学习过的作用域之间会有非常
好的配合。使用嵌入也会很好地扩充我们的工具集,特别是在创建可以在团队、项目、AngularJS
社区之间共享的HTML代码片段时。
嵌入通常用来创建可复用的组件,典型的例子是模态对话框或导航栏。
我们可以将整个模板,包括其中的指令通过嵌入全部传入一个指令中。这样做可以将任意内
容和作用域传递给指令。 transclude 参数就是用来实现这个目的的,指令的内部可以访问外部
指令的作用域,并且模板也可以访问外部的作用域对象。
为了将作用域传递进去, scope 参数的值必须通过 {} 或 true 设置成隔离作用域。如果没有设
置 scope 参数,那么指令内部的作用域将被设置为传入模板的作用域。
只有当你希望创建一个可以包含任意内容的指令时,才使用 transclude: true 。
3.常见问题
如何创建操作DOM的指令?
4.解决方案
要修改DOM的指令通常使用链接选项来注册DOM侦听器以及更新DOM。它是在模板被克隆后执行的,是指令逻辑将被执行的地方。
链接的功能与下面的签名,功能链接(scope,element,attrs,controller,transcludeFn){…},:
scope是一个Angular scope 对象。
element是这个指令匹配的jqlite包装元素。
attrs是一个哈希对象,其具有键值对标准化属性名及其相应的属性值。
controller是指令的必需控制器实例(s)或它自己的控制器(如果有的话)。确切的值取决于指令的要求属性。
transcludeFn是一个连接函数预绑定到正确的连接函数。
在我们的link函数中,我们希望每秒更新显示的时间,或者每当用户更改指令绑定到的时间格式字符串时。
我们将使用$ interval服务定期调用处理程序。这比使用$ timeout更容易,但也可以更好地使用端到端测试,
我们希望确保在完成测试之前完成所有$ timeouts。如果指令被删除,我们还希望删除$ interval,这样我们就不会引入内存泄漏。
5.编码实战
6.扩展思考
创建一个包含其他元素的指令
7.参考文献
angular自定义指令官方指南
流浪猫の窝
8.更多讨论
1.为什么不推荐Angular和JQuery混合使用?
Angular在DOM操作上面不如jQuery方便,而jQuery在页面的数据构造方面不如Angular方便
那么Angular的jqlite怎么样呢,确实这个东西能够提供最基础的DOM操作,可以保证你够用,但是在你能够自己写出各种动效插件之前,其实你还是需要使用到其他人写到的插件的。
2.什么是内存泄漏?
内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
3.scope里的@&=是什么意思?
directive 在使用隔离 scope 的时候,提供了三种方法同隔离之外的地方交互。这三种分别是:
@ 绑定一个局部 scope 属性到当前 dom 节点的属性值。结果总是一个字符串,因为 dom 属性是字符串。
& 提供一种方式执行一个表达式在父 scope 的上下文中。如果没有指定 attr 名称,则属性名称为相同的本地名称。
= 通过 directive 的 attr 属性的值在局部 scope 的属性和父 scope 属性名之间建立双向绑定。