如何防止在Angular中双击? [英] How to prevent double click in Angular?

查看:207
本文介绍了如何防止在Angular中双击?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有click的组件.

<my-box (click)="openModal()"></my-box>

当我单击此元素时,openModal函数将运行. 而且我想给1000ms的油门时间,以防止打开多个模式.

When I click this element, openModal function will run. And I'd like to give 1000ms throttle time in order to prevent opening multiple modals.

我的第一个方法是使用Subject(来自rxJs)

My first approach was using Subject (from rxJs)

//html
<my-box (click)="someSubject$.next()"></my-box>
//ts
public someSubject$:Subject<any> = new Subject();
...etc subscribe

但是我觉得这有点冗长.

But I feel it's a bit verbose.

下一个方法是使用directive. 我修改了通过谷歌搜索找到的一些代码.

Next Approach was using a directive. I modified a bit of code that I found by googling.

//ts
import {Directive, HostListener} from '@angular/core';

@Directive({
    selector: '[noDoubleClick]'
})
export class PreventDoubleClickDirective {

    constructor() {
    }

    @HostListener('click', ['$event'])
    clickEvent(event) {
        event.stopPropagation();    // not working as I expected.
        event.preventDefault();     // not working as I expected.

        event.srcElement.setAttribute('disabled', true);    // it won't be working unless the element is input.
        event.srcElement.setAttribute('style', 'pointer-events: none;');   // test if 'pointer-events: none' is working but seems not. 

        setTimeout(function () {
            event.srcElement.removeAttribute('disabled');
        }, 500);
    }
}

//html
<my-box noDoubleClick (click)="openModal()"></my-box>

但是,无论我如何尝试,总是执行openModal. 我找不到如何停止执行指令中的openModal.

However, whatever I try, always openModal was executed. I couldn't find how to stop executing openModal in the directive.

我可以像

//ts
//In the openModal method.
openModal() {
    public isClickable = true

    setTimeout(() => {
        this.newsClickable = true;
    }, 1000);
    ...
}

但是对于可重用的代码,我认为使用指令是理想的选择.

But for the reusable code, I think using directive is ideal.

我该怎么做?

推荐答案

您可以使用RxJs的 debounceTime 运算符可防止双击. 此处也是有关如何创建一个自定义的防抖动click指令.

You can use RxJs' debounce or debounceTime operator to prevent double clicks. Here is also a post on how to create a custom debounce click directive.

以防将来删除该帖子,这是最终代码:

In case the post is taken down in the future, here is the final code:

import { 
  Directive, 
  EventEmitter, 
  HostListener, 
  Input, 
  OnDestroy, 
  OnInit, 
  Output 
} from '@angular/core';
import { Subject, Subscription } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

@Directive({
  selector: '[appDebounceClick]'
})
export class DebounceClickDirective implements OnInit, OnDestroy {
  @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);
  }
}

用法示例:

<button appDebounceClick (debounceClick)="log()" [debounceTime]="700">Debounced Click</button>

这篇关于如何防止在Angular中双击?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆