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

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

问题描述

我有一个带有 click 的组件.

I have a component with 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

但我觉得它有点冗长.

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

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);
    ...
}

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

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

我该怎么做?

推荐答案

你可以使用 RxJs 的 debouncedebounceTime 运算符以防止双击.这里也是一篇关于如何创建的帖子自定义去抖动点击指令.

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天全站免登陆