首页 > 解决方案 > 在 debounceTime 之后多次调用函数

问题描述

我有一个带有一个字段的反应式表单,当用户停止输入时,我想将值打印到控制台。为此,我debounceTime()在字段中的值发生更改时使用。我读了几个关于如何在角度组件中使用 debounceTime 的问题debounceTime()?和Angular 和 debounce但我的代码不止一次打印最新值,然后检测到更改并且 debounceTime 函数中的时间已经过去。

表单的输入字段是这样的:

<input matInput formControlName="name" (keyup)="onInputChange()">

函数 onInputChange 中的代码是这样的:

this.userForm.get("name").valueChanges
          .pipe(
            debounceTime(500)
          )
          .subscribe(res => {
            console.log(res)
          });

它的输入是test控制台中的结果,如下图所示:

在此处输入图像描述

有什么问题?

标签: angularrxjs

解决方案


您正在调用一个函数并在每次按键时订阅,您只需要订阅一次而不调用 (keyup) 函数,因为这将捕获对输入的任何更改。

看起来正在调用的函数可能会导致创建四个订阅,因此控制台中有四个条目。

<input matInput formControlName="name" (keyup)="onInputChange()">

应该只是

<input matInput formControlName="name">

将此逻辑移动到您ngOnInit()的组件中,以便在组件生命周期的早期创建订阅,并且只创建一次。

然后,您可以制作该名称的无参考副本并在valuesChanged()块中进行比较,以确保它与发布前的原始名称不匹配。

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
        }
      });
    });
}

还建议阅读如何在组件被销毁时处理订阅,因为这不会处理它自己,有很多可用资源。


推荐阅读