繁体   English   中英

Angular valueChanges updateOn:模糊在提交之前如何等待所有值更改完成

[英]Angular valueChanges updateOn: blur how to wait before all valuechanges completed before submit

我有一个反应式表单,其中包含我订阅的一些字段。 用户在订阅的控件上输入一个值,选项卡或单击字段(模糊事件),将进行后端/http调用以获取一些附加信息并填充一些其他字段。

这一切都完美无缺。

当用户没有点击字段外而是直接点击我们的保存按钮时,就会出现问题,该按钮在保存之前启动逻辑。 100 次中有 70 次也可以,后端调用足够快以获取附加信息,然后开始保存过程,但其他 30 次我们缺少一些信息。

当然,我可以做一些手动检查和验证器,但我认为必须有一种方法来确保我所有的 valuechange 都没有挂起并确保它们都已完成。

非常感谢!

您可以在 API 正在进行时禁用该按钮。

- 维护一个 boolean 变量并使用点击运算符更新其值。在内部使用switchMap运算符进行 API 调用,一旦完成,禁用 boolean 值。

this.firstName.valueChanges
          .pipe(
            tap((x) => (this.isLoading = true)),
            switchMap(() => {
              return of('xxxx').pipe(delay(2000));
            }),
            tap((x) => (this.isLoading = false))
          )
          .subscribe((x) => console.log(x));

- 使用 boolean 变量禁用按钮

<button [disabled]="isLoading">Submit</button>

这样,您的按钮将默认启用,但是一旦用户开始在文本框中输入内容,按钮就会被禁用,直到 API 响应完成。

演示:- https://stackblitz.com/edit/angular-ivy-kheete?file=src%2Fapp%2Fapp.component.ts

注意:- 添加了延迟以展示工作流程。

所以我想我找到了一种解决方案。 也许我可以进一步扩展它,所以我不必将布尔值放在我所有的 valuechanges 函数中,但现在这似乎工作正常。

在我的触发值更改 function 中,我从 boolean 开始设置为 true 以标记我们当前正在进行活动值更改。

例子:

async valueChangeFunc() {
this.activeValueChanges = true;
//await..http call 
//more logic
this.activeValueChanges = false;
}

在我提交的 function 中,我将等到活动值更改 boolean 被解析为 false。

例子:

 async submitForm() {
    await waitFor(() => !this.activeValueChanges);
    //mark formcontrols as touched etc.
    const values = this.myForm.getRawValue();
    const errors = getValidationErrors(this.myForm);
    //more logic
}

这一切的关键是以下 function 在继续之前等待

const waitFor = async (condFunc: () => boolean) => {
  return new Promise<void>((resolve) => {
    if (condFunc()) {
      resolve();
    }
    else {
      setTimeout(async () => {
        await waitFor(condFunc);
        resolve();
      }, 100);
    }
  });
};

希望它可以帮助某人,现在工作 100 次中的 100 次

如果监听 valuechanges 对您的用户体验很重要,而不是为用户设置一个按钮来提交他的更改,则处理起来很棘手。 您可以为此 senario 制作一个开箱即用的 sloution,例如:

JSON.stringify(value):使值易于跟踪其更改。

distinictUntilChanged():不会两次发出相同的值。

debounceTime(500):在本例中,从最后一次发出值后需要经过的时间为 500 毫秒。

JSON.parse(value):将值返回到原来的state。

this.form.valuechanges.pipe(
  map(value => JSON.stringify(value),
  distinictUntilChanged(),
  debounceTime(500),
  map(value => JSON.parse(value)))
  .subscribe(value => {
    ...Your Code
  });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM