Angular4 创建自定义指令Directive学习文档 节流指令

1,473 阅读3分钟

写在最前面: 作为一个很基础的学习文档,我只能将自己学习的理解及遇到的为数不多的坑分享出来,一定会有曲解和不足,请以借鉴为主,同时欢迎指正共同提高,切勿盲目照搬。

1 - 自定义指令是什么

自定义属性型指令至少需要一个带有@Directive装饰器的控制器类。该装饰器指定了一个用于标识属性的选择器。 控制器类实现了指令需要的指令行为。

个人理解其中关键点:1.带有@Directive装饰器;2.实现需要的指令行为;

也就是说如同*ngIf*ngFor等指令一样,用于实现特定的行为。

2 - 自定义指令能实现什么

上述说到,能够实现特定行为,抛砖引玉,用一个场景描述一下: 当前业务要求多个页面,多个组件,多个下载按钮,为了防止用户频繁点击下载按钮,需要一个节流操作,在点击下载的5秒内不允许再次点击 刚入职的我(勤快的我):每一个下载事件使用一个setTimeOut(); 工作了一段时间的我(有点懒的我):在公用js库中写一个setTimeOut()方法,在每个组件中引入,每个点击事件嵌入; 学到了Directive的我(很懒的我):创建一个自定义的节流指令,声明在公共module,在下载事件button上复制粘贴;

如果,这时候BOSS告诉你,5秒有点长,想要2秒,同时点击之后button变个好看的五彩斑斓黑色,那么...万一又要再点击之后再加个什么鬼的3s提示框呢?

。。。。。。我想应该是说的比较清晰(比较现实)了。

3 - 创建自定义指令

既然是// 带有@Directive装饰器的控制器类,那么一定是需要一个@Directive装饰器,在指定文件夹下新建文件debounce-click.directive.ts,使用angular-cli的话就更棒了,切到所需文件下,cmd输入ng g d debounce-click => 回车;

新建如下:

创建新的Directive

import引入Directive@Directive装饰器声明类型,DebounceClickDirective是该控制器类名; Directive也可以看做是组件,因此,请在对应的module中声明它(注1)!

注1: 在Angular中,同一组件/指令是无法在两个module中声明并导出的,因此,如果一个组件/指令要服务于多个module下的组件,可以采取两种方式(推荐第二种) 1.在需要引用的module的更高级中声明组件/指令,简单来说就是在app.module中导出,那么你在哪里都可以用啦,不过试想一下混乱的app.module... 2.创建一个公共module专门放置公共组件/公共指令(记得exports),当其他module需要引用时将该公共module引入,这么做的另一个好处就是...CommonModuleFormsModule这类公用module引用一次就OK了。

4 - 编写自定义指令

先上效果图;

完整代码

下载button节流

OK,逐行的解读一下关键字都是干啥的;

  1. import 'rxjs/add/operator/throttleTime':Rxjs已经封装好的强大的节流事件,拿过来直接用;
  2. selector:选择器,引用Directive的时候,谁还没个代号不是;
  3. @Output():作为输出项,在该指令中更多的是作为过渡作用;
  4. @Input('time'):延迟的时间可以自定义;
  5. clicks:声明一个主体对象,也就是被观察者;
  6. ElementRef:获取dom的实例,上述场景要改颜色啥的,你会用到的;
  7. @HostListener('click', ['$event']):监听宿主的事件,我个人理解就是监听...,第一个参数事件,第二个$event参数;
  8. doClick():当监听到宿主执行事件后的操作;

整体思路/流程:

当点击‘导出’按钮,进入自定义指令,订阅clicks被观察者,当满足当前时间与上次点击时间小于time秒时(throttle事件请看源码(注2)),将被观察者的event事件继续进行下去,否则停止。

注2:Rxjs防抖与节流源码解析地址。www.cnblogs.com/fsjohnhuang…