Angular中自定义Debounce Click指令防止重复点击
在这篇文章中,我们将介绍使用AngularDirectiveAPI来创建自定义debounceclick指令。该指令将处理在指定时间内多次点击事件,这有助于防止重复的操作。
对于我们的示例,我们希望在产生点击事件时,实现去抖动处理。接下来我们将介绍DirectiveAPI,HostListenerAPI和RxJS中debounceTime操作符的相关知识。首先,我们需要创建DebounceClickDirective指令并将其注册到我们的app.module.ts文件中:
import{Directive,OnInit}from'@angular/core'; @Directive({ selector:'[appDebounceClick]' }) exportclassDebounceClickDirectiveimplementsOnInit{ constructor(){} ngOnInit(){} } @NgModule({ imports:[BrowserModule], declarations:[ AppComponent, DebounceClickDirective ], providers:[], bootstrap:[AppComponent] }) exportclassAppModule{}
Angular指令是没有模板的组件,我们将使用以下方式应用上面的自定义指令:
DebouncedClick
在上面HTML代码中的宿主元素是按钮,接下来我们要做的第一件事就是监听宿主元素的点击事件,因此我们可以将以下代码添加到我们的自定义指令中。
import{Directive,HostListener,OnInit}from'@angular/core'; @Directive({ selector:'[appDebounceClick]' }) exportclassDebounceClickDirectiveimplementsOnInit{ constructor(){} ngOnInit(){} @HostListener('click',['$event']) clickEvent(event:MouseEvent){ event.preventDefault(); event.stopPropagation(); console.log('ClickfromHostElement!'); } }
在上面的例子中,我们使用了Angular@HostListener装饰器,该装饰器允许你轻松地监听宿主元素上的事件。在我们的示例中,第一个参数是事件名。第二个参数$event,这用于告诉Angular将点击事件传递给我们的clickEvent()方法。
在事件处理函数中,我们可以调用event.preventDefault()和event.stopPropagation()方法来阻止浏览器的默认行为和事件冒泡。
DebounceEvents
现在我们可以拦截宿主元素的click事件,此时我们还需要有一种方法实现事件的去抖动处理,然后将它重新发送回父节点。这时我们需要借助事件发射器和RxJS中的debounce操作符。
import{Directive,EventEmitter,HostListener,OnInit,Output}from'@angular/core'; import{Subject}from'rxjs/Subject'; import'rxjs/add/operator/debounceTime'; @Directive({ selector:'[appDebounceClick]' }) exportclassDebounceClickDirectiveimplementsOnInit{ @Output()debounceClick=newEventEmitter(); privateclicks=newSubject(); constructor(){} ngOnInit(){ this.clicks .debounceTime(500) .subscribe(e=>this.debounceClick.emit(e)); } @HostListener('click',['$event']) clickEvent(event:MouseEvent){ event.preventDefault(); event.stopPropagation(); this.clicks.next(event); } }
在上面的代码中,我们使用Angular@Output属性装饰器和EventEmitter类,它们允许我们在指令上创建自定义事件。要发出事件,我们需要调用EventEmitter实例上的emit()方法。
但我们不想立即发出点击事件,我们想做去抖动处理。为了实现这个功能,我们将使用RxJS中的Subject类。在我们的代码中,我们创建一个主题来处理我们的点击事件。在我们的方法中,我们调用next()方法来让Subject对象发出下一个值。此外我们也使用RxJS中debounceTime的操作符,这允许我们通过设置给定的毫秒数来去抖动点击事件。
一旦我们设置好了,我们现在可以在下面的模板中监听我们的自定义去抖动点击事件。
DebouncedClick
现在,当我们点击我们的按钮时,它将延迟500毫秒。500毫秒后,我们的自定义输出属性将会发出点击事件。现在我们有了基本的功能,我们需要做一些清理工作,并增加一些其它的功能。
Unsubscribe
对于RxJS中Observables和Subject对象,一旦我们不再使用它们,我们必须取消订阅事件。如果我们没有执行取消订阅操作,有可能会出现内存泄漏。
import{Directive,EventEmitter,HostListener,OnInit,Output,OnDestroy}from'@angular/core'; import{Subject}from'rxjs/Subject'; import{Subscription}from"rxjs/Subscription"; import'rxjs/add/operator/debounceTime'; @Directive({ selector:'[appDebounceClick]' }) exportclassDebounceClickDirectiveimplementsOnInit,OnDestroy{ @Output()debounceClick=newEventEmitter(); privateclicks=newSubject(); privatesubscription:Subscription; constructor(){} ngOnInit(){ this.subscription=this.clicks .debounceTime(500) .subscribe(e=>this.debounceClick.emit(e)); } ngOnDestroy(){ this.subscription.unsubscribe(); } @HostListener('click',['$event']) clickEvent(event:MouseEvent){ event.preventDefault(); event.stopPropagation(); this.clicks.next(event); } }
要取消订阅,我们需要保存订阅时返回的订阅对象。当Angular销毁组件时,它将调用OnDestroy生命周期钩子,因此我们可以在这个钩子中,执行取消订阅操作。
CustomInputs
我们指令的功能已基本齐全,它可以正常处理事件。接下来,我们将添加一些更多的逻辑,以便我们可以自定义去抖动时间。为此,我们将使用@Input装饰器。
import{Directive,EventEmitter,HostListener,OnInit,Output,OnDestroy,Input}from'@angular/core'; import{Subject}from'rxjs/Subject'; import{Subscription}from"rxjs/Subscription"; import'rxjs/add/operator/debounceTime'; @Directive({ selector:'[appDebounceClick]' }) exportclassDebounceClickDirectiveimplementsOnInit,OnDestroy{ @Input()debounceTime=500; @Output()debounceClick=newEventEmitter(); privateclicks=newSubject(); privatesubscription:Subscription; constructor(){} ngOnInit(){ this.subscription=this.clicks .debounceTime(this.debounceTime) .subscribe(e=>this.debounceClick.emit(e)); } ngOnDestroy(){ this.subscription.unsubscribe(); } @HostListener('click',['$event']) clickEvent(event:MouseEvent){ event.preventDefault(); event.stopPropagation(); this.clicks.next(event); } }
@Input装饰器允许我们将自定义延迟时间传递到我们的组件或指令中。在上面的代码中,我们可以通过组件的输入属性,来指定我们希望去抖动的时间。默认情况下,我们将其设置为500毫秒。
DebouncedClick
参考资源
creating-a-custom-debounce-click-directive-in-angular
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。