我的场景是,当收到新的 tagid 事件时,我必须将其显示在角度形式的文本框中。然后设置一个 5 秒的计时器,如果没有收到新事件,则清除文本框。如果收到新事件,则必须停止之前设置的计时器并安排计时器。
我的代码如下。在这种情况下,如果连续多次接收到相同的 tagid,则文本框将被清除,而不是重新创建计时器。
如何使用 rxjs 和 Angular 实现所需的逻辑?
@Input() tagId$: Observable<string>;
const delay$ =
this.tagId$.pipe(delay(5000));
combineLatest([
this.tagId$,
delay$,
]).pipe()
.subscribe(([tag, delayedTag]) => {
let value = tag;;
if (tag === delayedTag) {
console.log('tag$$ cleared by delay', tag, delayedTag);
value = '';
}
this.tagIdFormElement?.setValue(value);
this.form.markAsDirty();
});
debounceTime
来取消之前的事件并重置计时器,因此只有在 5 秒没有事件发生后,您才会发生重置,工作示例如下!
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { bootstrapApplication } from '@angular/platform-browser';
import { Subject, tap } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import 'zone.js';
@Component({
selector: 'app-root',
standalone: true,
imports: [ReactiveFormsModule, CommonModule],
template: `
<form [formGroup]="form">
<input type="text" formControlName="item"/>
</form>
<button (click)="setVal()">set value</button>
`,
})
export class App {
dummy: Subject<string> = new Subject<string>();
name = 'Angular';
form = new FormGroup({
item: new FormControl(''),
});
get item(): FormControl {
return <FormControl>this.form.get('item');
}
setVal() {
console.log('a', new Date());
this.dummy.next(
'this will clear in 5 second if new event not there: ' + Math.random()
);
}
ngOnInit() {
this.dummy
.pipe(
tap((value: string) => {
this.item.setValue(value);
}),
debounceTime(5000)
)
.subscribe(() => {
console.log('b', new Date());
console.log('time to clear!');
this.item.setValue('');
});
}
}
bootstrapApplication(App);