我有一个带有一个字段的响应式(Reactive)表单,当用户停止输入时,我想将值打印到控制台。为此,当字段中的值更改时,我使用了 debounceTime()
。
我读了几个关于使用 debounceTime()
的问题,比如 How to use debounceTime in an angular component?和 Angular and debounce但是我的代码多次打印最新值,然后检测到更改并且 debounceTime 函数中的时间已经过去。
表单的输入字段是这样的:
<input matInput formControlName="name" (keyup)="onInputChange()">
onInputChange函数中的代码是这样的:
this.userForm.get("name").valueChanges
.pipe(
debounceTime(500)
)
.subscribe(res => {
console.log(res)
});
如果输入是test
,控制台的结果如下图:
有什么问题吗?
最佳答案
您正在调用一个函数并在每次按键时订阅,您只需要订阅一次而不需要调用 (keyup) 函数,因为这将捕获对输入的任何更改。
看起来正在调用的函数可能会导致创建四个订阅,因此控制台中有四个条目。
<input matInput formControlName="name" (keyup)="onInputChange()">
应该只是
<input matInput formControlName="name">
将此逻辑移到您的 ngOnInit()
中,以便在组件生命周期的早期创建订阅,并且只创建一次。
然后您可以复制该名称的无引用副本,并在 valuesChanged()
block 中进行比较,以确保它与发布前的原始名称不匹配。
userForm = this.formBuilder.group({
name: ['']
)};
public originalName = '';
public ngOnInit(): void
{
this.userService.getUserById(this.userId).subscribe(res =>
{
this.originalName = JSON.parse(JSON.stringify(res.name));
this.userForm.controls['name'].setValue(res.name);
this.userForm.get("name").valueChanges.pipe(debounceTime(500)).
subscribe(res =>
{
if (res.name !== this.originalName)
{
// logic to post to server
}
});
});
}
还建议阅读如何在组件被销毁时处理订阅,因为这不会自行处理,有很多可用资源。
关于angular - 函数在 debounceTime 后被多次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57595188/