[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














留言

這個網誌中的熱門文章

[Angular] 閒置登出作法

[Angular Materail] 檔案上傳範例

[Angular Material] 搜尋式下拉選單範例