角度形式控制最后可观察到的变化

时间:2017-12-20 03:59:16

标签: angular typescript autocomplete rxjs angular-observable

我正在构建一个自动完成功能,它正在查询后端的建议,并且只想在用户键入角度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毫秒后查询[',' te' tes' tes' test' test']。如何在3000毫秒延迟后从valueChanges中取出最后一次更改(即' test'),然后进行订阅?谢谢你的帮助

1 个答案:

答案 0 :(得分:3)

您想要的是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不同,switchMap将在制作完成后3秒发出所有更改。
  • getAddressSuggestions接受一个内部可观察对象,例如http请求,并将可观察流更改为它 - 即您现在订阅了switchMap可观察流。如果某些内容发送到getAddressSuggestions,它将取消之前的observable。结果是,如果之前进行的catchError呼叫在新呼叫开始之前尚未完成,则前一呼叫将被取消。
  • .catch({1}}的可调运算符版本用于getAddressSuggestions observable而不是valueChanges。否则,如果API出错,则valueChanges observable将完成。使用catchError允许您在不完成valueChanges observable的情况下处理错误。
  • filter用于仅发出具有值的响应。如果出现错误,则of()不会被发出。这只是解决这种情况的一种方法。

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