- 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效 throttle
- 防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时 debounce
之前说起节流防抖,都是在事件内部用RXJS处理的(最开始写的是原生,设定计时器和开关)。后来看到别人把节流防抖放在 Angular 指令 Directives里,并且使用@output装饰器触发元素的指定事件。
太妙了。
import { Directive, EventEmitter, HostListener, OnInit, Output, OnDestroy } from '@angular/core';
import { Subject, Subscription } from 'rxjs';
import { throttleTime } from 'rxjs/operators';
/**
* 点击节流器:避免连续点击
*/
@Directive({
selector: '[directive-throttle]'
})
export class ThrottleClickDirective implements OnInit, OnDestroy {
// 一定的时间内只执行第一个事件
private THROTTLE_TIME: number = 500;
private subject = new Subject<MouseEvent>();
private click: Subscription;
// 事件方法
@Output() throttleClick = new EventEmitter();
constructor() { }
ngOnInit(): void {
const result = this.subject.pipe(
throttleTime(this.THROTTLE_TIME)
);
this.click = result.subscribe(e => {
this.throttleClick.emit(e)
})
}
ngOnDestroy() {
this.click.unsubscribe();
}
@HostListener('click', ['$event'])
onClick(evt: MouseEvent) {
this.subject.next(evt);
}
}
代码不多,但是涉及到的知识点很多。
1. RXJS subject
https://angular.cn/api/core/HostListenerhttps://angular.cn/api/core/HostListener
思考:@Directive + @HostListener 的使用应该可以做很多有意思的的事情。之前对指令的认知仅仅是停留在校验器的使用。
或许可以开发更多的玩法?