Angular 2 directive处理多次点击提交问题

    在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就可以了

猜你喜欢

转载自blog.csdn.net/xiaoguangtouqiang/article/details/79639721