大家好,我是IT修真院深圳分院第九期的学员徐炜,一枚正直纯洁善良的前端程序员。今天给大家带来的是怎么将分页封装成指令?
一.背景介绍
对于指令,可以把它简单的理解成在特定DOM元素上运行的函数,指令可以扩展这个元素的功能。 例如,一些原生的指令如 ng-disabled , ng-if ,ng-repeat ,ng-click 等。ng-click可以让一个元素能够监听click事件,并在接收到事件的时候执行AngularJS表 达式。正是指令使得AngularJS这个框架变得强大,并且在AngularJs我们可以自己通过directive来创造新的指令。
二.知识剖析
当在我们的项目中需要实现一些功能,比如,时间筛选、分页的功能,我们最先想到的可能是先去网上找找看, 有没有相应的插件可以给我们直接拿来使用。但是插件代码一般十分复杂,无法定位bug进行修改, 也无法保证修改后不会出现别的bug,用起来可能不太顺手。像一些实现简单功能的插件, 我们可以利用AngularJS中的directive自己写一个指令,进行封装,也可以方便以后重复使用。
三.常见问题
怎么将分页封装成指令?
四.解决方案
先了解一下DIRECTIVE自定义指令中都可以设置哪些选项?
(1)restrict: String,可选字符串参数,可以设置这个指令在DOM中可以何种形式被声明,默认为A(属性) 设置为“E”(标签) 设置为"C"(类名) M(注释) <--directive:my-directive expression-->。
(2)priority: Number ,优先级,可忽略,默认为0, ngRepeat的优先级为1000,这样就可以保证在同一元素上,它总是在其他指令之前被调用
(3)terminal:boolean,默认为false,如果为true则停止运行当前元素上比本指令优先级更低的指令,优先级相同的指令还是会被执行。template:string or Template Function 指令中重要的属性,必须设置如下一种 1.一段html文本 2.可以接受两个参数的函数 模板中必须只有一个根标签。 当html过长时,可以设置templateUrl引用 templateUrl: String 接受一个路径的字符串,还可以在script标签中写模板。
(4)template:string or Template Function 指令中重要的属性,必须设置如下一种 1.一段html文本 2.可以接受两个参数的函数 模板中必须只有一个根标签。 当html过长时,可以设置templateUrl引用 templateUrl: String 接受一个路径的字符串,还可以在script标签中写模板。
(4)replace: Boolean, 默认为false(模板内容会加载到标签内部),true(模板内容会替换当前标签) transclude: Boolean 是否使用ng-transculde来包含html中原有的内容,接收两个参数true/false。默认为false 如果指令使用了 transclude 参数,那么在指令里的控制器中就无法正常监听数据模型的变化了。
(5)scope: Boolean or Object 默认为false。直接使用父scope,比较危险。 设置为true,继承父scope 设置为对象,创建一个新的隔离的scope,仍然可以与父scope通信 对象中可设置的绑定方式有三种: 1.@ 单向绑定,外部scope能影响内部scope,但反过来不成立 2.= 双向绑定,外部scope和内部scope的model能够互相改变 3.& 在父scope的上下文中执行一个表达式。此表达式可以是一个function。
(6)controller: String or function(scope, element, attrs, transclude, otherInjectables) { ... } 注册在应用中的控制器的构造函数 一般是写为呈现视图之前而准备的数据或者是与其他指令进行数据交互而暴露这个api controllerAs: String 这个选项是用来设置控制器的别名的。
(7)compile 和 link 选项是互斥的。如果同时设置了这两个选项,那么会把 compile所返回的函数当作链接函数,而 link 选项本身则会被忽略。 通常情况下,如果设置了 compile 函数,说明我们希望在指令和实时数据被放到DOM中之前进行DOM操作,在这个函数中进行诸如添加和删除节点等DOM操作是安全的。
五.编码实战
实战演示demo,详见视频。
六.扩展思考
除了分页组件还可以自定义什么组件?
1、凡是可以复用的组件,例如上传图片,请求,侧边栏等等,都可以拿来封装成自定义指令。
2、根据项目实际需求,可以自定义项目需要的组件。
七.参考文献
参考二:angular 自定义指令详解 Directive;
八.更多讨论
问题一:我们的指令是如何利用这些前缀标识符来寻找我们想要的属性或者函数的 ?
答:@当指令编译到模板的name时,就会到scope中寻找是否含有name的键值对,如果存在,就像上面那样,看到@就知道这是一个单向的数据绑定,然后寻找原来的那个使用指令的元素上(或者是指令元素本身)含有这个值的属性即my-name={{name}},然后在父作用域查找{{name}}的值,得到之后传递给模板中的name。=和&与@差不多,只不过=进行的是双向的数据绑定,不论模板还是父作用域上的属性的值发生改变都会使另一个值发生改变,而&是绑定函数而已。
问题二: 怎么实现分页的页码功能?
答:插件有两个关键参数currentPage、itemsPerPage,当前页码和每页的记录数。实现方法调用后我们需要根据每次点击分页插件页码时重新提交后台来获取相应页码数据。
问题三:怎么获取分页的总页码?
答:根据总的数据和每页显示的条数来计算即可。
感谢黄源志和陈杰超师兄,此教程是在他们之前技术分享的基础上完善而成。
今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~