Angular 表单控件最后可观察到的变化

Angular form control last observable change

我正在构建一个自动完成功能,该功能正在查询后端以获取建议,并且希望仅在用户输入 angular 5 表单控件时获得在给定一定延迟的情况下进行的最后一次查询。目前我的代码看起来像

 this.newVendorForm.get('address').valueChanges.pipe(delay(3000)).subscribe(
  address => {
    this.geocodeApi.getAddressSuggestions(address)
      .subscribe(
        response => {
          console.log('address suggestions');
          console.log(response);
          this.addressSuggestions = response;
        },
        error => {
          console.log('error getting address suggestion');
          console.log(error);
        }
      )
  }
);

这有效,但是它会在 3000 毫秒后查询每个输入的字母。例如 'test' 将在 3000 毫秒后查询 ['t'、'te'、'tes'、'test']。我怎样才能在 3000 毫秒延迟后从 valueChanges 中获取最后一次更改(即 'test')然后进行订阅?谢谢你的帮助

你想要的是 debounceTimeswitchMap 的混合。

this.newVendorForm.get('address').valueChanges.pipe(
  debounceTime(3000),
  switchMap(address => this.geocodeApi.getAddressSuggestions(address).pipe(
    catchError(err => {
      console.error(err);
      return of();
    })
  )),
  filter(Boolean),
).subscribe(response => this.addressSuggestions = response);
  • debounceTime 使得如果在 3 秒内有两个 valueChanges 发射,则只使用最后一个。这与 delay 不同,后者将在更改完成 3 秒后发出所有更改。
  • switchMap 接受一个内部可观察对象,例如 http 请求,并将可观察流更改为它——即您现在订阅了 getAddressSuggestions 可观察流。如果有东西发射到 switchMap,它会取消之前的可观察值。这样做的结果是,如果先前进行的 getAddressSuggestions 调用在新调用开始之前尚未完成,则前一个调用将被取消。
  • catchError.catch 的可出租运算符版本)用于 getAddressSuggestions 可观察对象而不是 valueChanges。否则,如果 API 出现错误,valueChanges 可观察值将完成。使用 catchError 允许您在不完成 valueChanges observable 的情况下处理错误。
  • filter 用于仅发出具有值的响应。如果出现错误,将不会发出 of()。不过,这只是处理这种情况的一种方法。

最后,您可能希望避免使用手册 .subscribe,因为您将不得不 .unsubscribe。相反,您可以尝试依赖模板中的 | async 管道,它将为您处理订阅。