[Angular] 避免連點重複送出請求的方式
在Angualr中,经常需要处理多次短时间重复点击提交等操作;比如,页面的一些操作需要经常提交请求到后台处理数据,或者搜索功能对于每一个输入的字符都到后端搜索处理返回结果,对短时间内频繁的重复提交来说,我们只需要这段时间内最后一次的提交请求;否则这些无效的网络请求会加大服务器的负担;在angular中,我们可以通过创建一个延时执行的click的directive来处理这种情况;
1>首先需要定义个directive,监听当前元素的click事件;
import { Directive, HostListener, OnInit } from '@angular/core';
@Directive({
selector: '[appDebounceClick]'
})
export class DebounceClickDirective implements OnInit {
constructor() { }
ngOnInit() { }
@HostListener('click', ['$event'])
clickEvent(event) {
event.preventDefault();
event.stopPropagation();
console.log('Click from Host Element!');
}
}
HostListener这个装饰器可以监听directive作用的dom元素的click事件,第二个参数$event告诉Angular传递点击事件到directive中去; event.preventDefault();event.stopPropagation() 防止事件继续向parent component中传递;
2>Debounce Events
我们需要拦截点击事件然后延迟这些点击事件的执行,直到一段时间内最后一次点击,最后把事件的处理操作交给parent来处理;
import { Directive, EventEmitter, HostListener, OnInit, Output } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { debounceTime } from 'rxjs/operators';
@Directive({
selector: '[appDebounceClick]'
})
export class DebounceClickDirective implements OnInit {
@Output() debounceClick = new EventEmitter();
private clicks = new Subject();
constructor() { }
ngOnInit() {
this.clicks.pipe(
debounceTime(500)
).subscribe(e => this.debounceClick.emit(e));
}
@HostListener('click', ['$event'])
clickEvent(event) {
event.preventDefault();
event.stopPropagation();
this.clicks.next(event);
}
}
这里使用subject的.next来传递点击事件,然后使用rxjs的函数操作符debounceTime来处理延时事件,在指定事件内只处理最后一次操作,最后调用emit传递点击事件的操作到parent中去继续处理;
3>最后需要注意的是,destory中取消订阅,完整代码
import { Directive, EventEmitter, HostListener, OnInit, Output, Input } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { debounceTime } from 'rxjs/operators';
import {Subscription} from 'rxjs/Subscription';
@Directive({
selector: '[appDebounceClick]'
})
export class DebounceClickDirective implements OnInit {
@Input() debounceTime = 500;
@Output() debounceClick = new EventEmitter();
private clicks = new Subject();
private subscription: Subscription;
constructor() { }
ngOnInit() {
this.subscription = this.clicks.pipe(
debounceTime(this.debounceTime)
).subscribe(e => this.debounceClick.emit(e));
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
@HostListener('click', ['$event'])
clickEvent(event) {
event.preventDefault();
event.stopPropagation();
this.clicks.next(event);
}
}
这里将延迟时间作为参数传递进来;
页面使用该directive的方法
<button appDebounceClick (debounceClick)="log()" [debounceTime]="700">Debounced Click</button>
这样就可以需要重复大量提交的地方,加上该directive就可以了
————————————————
版权声明:本文为CSDN博主「xiaoguangtouqiang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xiaoguangtouqiang/article/details/79639721
留言
張貼留言