跟随此Stackblitz
我有一个指令,当您单击时,它应该禁用按钮直到一定时间(以防止双击)。
<button appThrottleClick (throttleClick)="click()">
BUTTON
</button>
<button appThrottleClick [disabled]="myValue" (throttleClick)="click()">
BUTTON VALUE
</button>
我希望该按钮禁用,然后在x秒后重新启用。在这里使用此指令:
@Directive({
selector: '[appThrottleClick]'
})
export class ThrottleClickDirective implements OnInit, OnDestroy {
@HostBinding('attr.disabled') disabled: boolean;
@Input() throttleTime = 200;
@Output() throttleClick = new EventEmitter();
private clicks = new Subject();
private subscription: Subscription;
constructor() { }
ngOnInit() {
this.subscription = this.clicks.pipe(
throttleTime(this.throttleTime)
).subscribe(e => {
this.throttleClick.emit(e);
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
@HostListener('click', ['$event'])
clickEvent(event) {
console.log('click')
if (this.disabled) { return; }
event.preventDefault();
event.stopPropagation();
this.disabled = true;
this.clicks.next(event);
setTimeout(() => { this.disabled = false; console.log('reset')}, this.throttleTime);
}
}
基本上:
如果未禁用该按钮,请单击一次,然后放置一个冷却时间,然后再次启用它。如果该按钮被禁用,请不要单击。
我遇到的问题,在单击并等待冷却后,再也不会重新启用它。即使禁用,也设置为false。
[在disabled
,attr.disabled
中使用HostBinding
时需要使用ThrottleClickDirective
而不是stackblitz sample:
...
export class ThrottleClickDirective implements OnInit, OnDestroy {
@HostBinding('disabled') disabled: boolean;
@Input() throttleTime = 200;
...
而不是使用@HostBinding
我们ElementRef
禁用和启用按钮,因此您的指令将为
import { Directive, EventEmitter, HostListener, Input, OnDestroy, OnInit, Output, HostBinding,ElementRef } from '@angular/core';
import { throttleTime } from 'rxjs/operators';
import { Subject, Subscription } from 'rxjs';
@Directive({
selector: '[appThrottleClick]'
})
export class ThrottleClickDirective implements OnInit, OnDestroy {
@Input() throttleTime = 1000;
@Output() throttleClick = new EventEmitter();
private clicks = new Subject();
private subscription: Subscription;
constructor(private _elementRef:ElementRef) { }
ngOnInit() {
this.subscription = this.clicks.pipe(
throttleTime(this.throttleTime)
).subscribe(e => {
this.throttleClick.emit(e);
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
@HostListener('click', ['$event'])
clickEvent(event) {
console.log('click')
event.preventDefault();
event.stopPropagation();
this._elementRef.nativeElement.disabled=true;
this.clicks.next(event);
setTimeout(() => {
console.log('reset')
this._elementRef.nativeElement.disabled=false;
}, this.throttleTime);
}
}