46 lines
1.4 KiB
TypeScript
46 lines
1.4 KiB
TypeScript
import { AfterViewInit, Directive, EventEmitter, Input, OnDestroy, Optional, Output } from '@angular/core';
|
|
import { NgModel } from '@angular/forms';
|
|
import { BooleanInput, InputBoolean, InputNumber, NumberInput } from '@delon/util';
|
|
import { Subscription } from 'rxjs';
|
|
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
|
|
@Directive({
|
|
selector: '[delay]:not([noDelay])',
|
|
exportAs: 'delayComp'
|
|
})
|
|
export class DelayDirective implements AfterViewInit, OnDestroy {
|
|
static ngAcceptInputType_delayTime: NumberInput;
|
|
static ngAcceptInputType_delayFirstEmit: BooleanInput;
|
|
|
|
private data$: Subscription | undefined;
|
|
private firstEmit = false;
|
|
|
|
@Input() @InputNumber() delayTime = 500;
|
|
@Input() @InputBoolean() delayFirstEmit = false;
|
|
@Output() readonly delayChange = new EventEmitter<any>();
|
|
|
|
constructor(@Optional() private ngModel: NgModel) {}
|
|
|
|
ngAfterViewInit(): void {
|
|
const { ngModel, delayFirstEmit, delayTime, delayChange } = this;
|
|
if (ngModel == null) {
|
|
return;
|
|
}
|
|
|
|
this.firstEmit = delayFirstEmit;
|
|
this.data$ = ngModel.valueChanges?.pipe(debounceTime(delayTime), distinctUntilChanged()).subscribe(res => {
|
|
if (this.firstEmit === false) {
|
|
this.firstEmit = true;
|
|
return;
|
|
}
|
|
delayChange.emit(res);
|
|
});
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
if (this.data$) {
|
|
this.data$.unsubscribe();
|
|
}
|
|
}
|
|
}
|