Téw*_*éwa 8 rxjs angular-directive angular
我有一个组件click.
<my-box (click)="openModal()"></my-box>
Run Code Online (Sandbox Code Playgroud)
当我单击此元素时,openModal函数将运行.而且我想给出1000ms的节流时间以防止打开多个模态.
我的第一种方法是使用Subject(来自rxJs)
//html
<my-box (click)="someSubject$.next()"></my-box>
//ts
public someSubject$:Subject<any> = new Subject();
...etc subscribe
Run Code Online (Sandbox Code Playgroud)
但我觉得它有点冗长.
Next Approach正在使用a directive.我修改了一些我通过谷歌搜索找到的代码.
//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>
Run Code Online (Sandbox Code Playgroud)
但是,无论我尝试什么,总是openModal被执行.我找不到如何openModal在指令中停止执行.
我可以这样做
//ts
//In the openModal method.
openModal() {
public isClickable = true
setTimeout(() => {
this.newsClickable = true;
}, 1000);
...
}
Run Code Online (Sandbox Code Playgroud)
但对于可重用的代码,我认为使用指令是理想的.
我该怎么做?
Jon*_*arr 41
由于有人要求该throttleTime指令,我将在下面添加它。我选择这条路线是因为debounceTime在触发实际点击事件之前等待最后一次点击。throttleTime在到达该时间之前,不允许点击器再次单击按钮,而是立即触发单击事件。
import { Directive, EventEmitter, HostListener, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { Subject, Subscription } from 'rxjs';
import { throttleTime } from 'rxjs/operators';
@Directive({
selector: '[appPreventDoubleClick]'
})
export class PreventDoubleClickDirective implements OnInit, OnDestroy {
@Input()
throttleTime = 500;
@Output()
throttledClick = new EventEmitter();
private clicks = new Subject();
private subscription: Subscription;
constructor() { }
ngOnInit() {
this.subscription = this.clicks.pipe(
throttleTime(this.throttleTime)
).subscribe(e => this.emitThrottledClick(e));
}
emitThrottledClick(e) {
this.throttledClick.emit(e);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
@HostListener('click', ['$event'])
clickEvent(event) {
event.preventDefault();
event.stopPropagation();
this.clicks.next(event);
}
}
Run Code Online (Sandbox Code Playgroud)
throttleTime 是可选的,因为指令中有一个默认值 500
<button appPreventDoubleClick (throttledClick)="log()" [throttleTime]="700">Throttled Click</button>
Run Code Online (Sandbox Code Playgroud)
如果您有一个机器人每 1 毫秒点击一次您的元素,那么您会注意到该事件在throttleTime启动之前只会触发一次。
Sam*_*ann 17
您可以使用RxJs' 反跳或debounceTime操作,以防止双击.这里还有一篇关于如何创建自定义去抖动点击指令的文章.
如果将来删除帖子,这里是最终代码:
import { Directive, EventEmitter, HostListener, Input, OnDestroy, OnInit,
Output } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Subscription } from 'rxjs/Subscription';
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);
}
}
Run Code Online (Sandbox Code Playgroud)
<button appDebounceClick (debounceClick)="log()" [debounceTime]="700">Debounced Click</button>
Run Code Online (Sandbox Code Playgroud)
Ste*_*erg 12
我提出了一种更简单的按钮方法:
import {Directive, ElementRef, HostListener} from '@angular/core';
const DISABLE_TIME = 300;
@Directive({
selector: 'button[n-submit]'
})
export class DisableButtonOnSubmitDirective {
constructor(private elementRef: ElementRef) { }
@HostListener('click', ['$event'])
clickEvent() {
this.elementRef.nativeElement.setAttribute('disabled', 'true');
setTimeout(() => this.elementRef?.nativeElement?.removeAttribute('disabled'), DISABLE_TIME);
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
<button n-submit (click)="doSomething()"></button>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9239 次 |
| 最近记录: |