角度 (2+) - 在数据绑定插值中获取延迟



我正在使用谷歌的位置建议API构建一个位置搜索输入。一切正常,结果几乎立即返回,但我在显示数据时遇到了几个问题。

  • 建议从服务返回,但有时可能需要几秒钟才能显示在视图中(您可以看到延迟,因为结果会立即显示在控制台中,但需要一些时间才能在视图中更改(
  • 有时,视图中显示的结果显示的是最后一组结果,而不是当前结果

我已经写了一个我试图在StackBlitz上做的基本副本,https://google-location-suggestions.stackblitz.io,但这里仍然有同样的问题。我已经更新了它,使其具有加载状态,可以更好地显示问题。

StackBlitz 链接与编辑器: https://stackblitz.com/edit/google-location-suggestions

我还在这里包含一个视频,以便您可以了解我的意思: https://vimeo.com/271476965

如果他们知道为什么会发生这种情况,我将不胜感激任何人的帮助。

"延迟"与变化检测有关,如果在输入位置搜索后单击文档,angular 将获取事件并刷新 DOM。

maps api在角度加载后下载,这使得地图代码在ngZone之外运行。我在阅读这篇文章时理解了这一点。

主要修复程序(正如您之前在答案中提到的(是使用ngZone.run在角度区域中运行代码:

private suggestions$ = new BehaviorSubject([]);
public search(location: string): void {
this.service.getPlacePredictions(
{
input: location,
componentRestrictions: { country: 'uk' }
},
(predictions, status) => this._ngZone.run(() => this.suggestions$.next(predictions.map(p => p.description)))
);
}

我还添加了一些其他改进:

在构造函数中仅加载一次 maps api 以避免已经加载的错误(堆栈闪电战 aot 也会导致多次加载服务,因此我将重新加载机制更改为左下角菜单上的页面(:

constructor(private mapsAPILoader: MapsAPILoader) {
this.mapsAPILoader.load().then(() => {
this.service = new google.maps.places.AutocompleteService();
console.log('Maps API loaded');
this.mapsApiLoading$.next(false);
});
}

您可以使用 rxjs 管道创建所需的可观察量:

this.locationSuggestions$ = this.locationForm.get('location').valueChanges.pipe(
filter(location => location && location !== ''),
switchMap(location =>
this.appService.getLocationSuggestions(location)));

这样,您可以使用以下方法直接订阅模板中的可观察量async

<ng-container *ngIf="locationSuggestions$ | async as suggestions; else loading">
{{ suggestions | json }}
</ng-container>
<ng-template #loading>
loading...
</ng-template>

有时,如果我足够快,我可以在加载地图 api 之前进行搜索,所以我添加了一个加载可观察量,让组件知道他何时可以开始搜索。

这是带有更改的新堆栈闪电战。

@ibenjelloun(谢谢(建议的问题是更改检测。

我实现了 Angular 的 NgZone 来运行更改检测,以便通过将代码包装在ngZone.run方法中来更新绑定

this.ngZone.run(() => {
this.locationSuggestionsLoading = false;
this.locationSuggestions = locations;
});

最新更新