繁体   English   中英

Angular(2+) - 在数据绑定插值中得到延迟

[英]Angular (2+) - getting a delay in data binding interpolation

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

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

我已经写了一篇关于我在StackBlitz上做什么的基本副本, https: //google-location-suggestions.stackblitz.io,这里仍然有同样的问题。 我已将其更新为具有更好地显示问题的加载状态。

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

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

如果他们知道为什么会这样,我会感激任何人的帮助。

“延迟”与变化检测有关,如果在进行位置搜索后单击文档,则角度将获取事件并刷新DOM。

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

主要修复(正如您之前在答案中提到的)是使用ngZone.run在Angular Zone中运行代码:

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)))
    );
  }

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

在构造函数中只加载一次映射api以避免已经加载的错误(也是stackblitz 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管道创建所需的observable:

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

这样您就可以使用async直接在模板中订阅您的o​​bservable:

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

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

这是带有变化的新stackblitz。

@ibenjelloun(谢谢)建议的问题是变化检测。

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

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

暂无
暂无

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

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