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')然后进行订阅?谢谢你的帮助
你想要的是 debounceTime
和 switchMap
的混合。
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
管道,它将为您处理订阅。
我正在构建一个自动完成功能,该功能正在查询后端以获取建议,并且希望仅在用户输入 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')然后进行订阅?谢谢你的帮助
你想要的是 debounceTime
和 switchMap
的混合。
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
管道,它将为您处理订阅。