Ng-Bootstrap Typeahead 错误样式 Google Maps Place Autocomplete

Ng-Bootstrap Typeahead Incorrect Style With Google Maps Place Autocomplete

我正在开发一个使用 Ng-Bootstrap 的 typeahead directive 的 Angular 4 应用程序。在 Wikipedia 示例中,他们对 Wikipedia 进行 api 调用并将结果显示在预输入框中。我正在尝试做同样的事情,但使用的是 Google 地图的位置自动完成服务。

按照 Wikipedia 示例,我创建了一个类似的服务,returns 一个包含自动完成位置的 Rxjs Observable。

search(term: string) {
    if (term === '') {
      return Observable.of([]);
    }

    return Observable.create(observer => {
        this.autocompleteService.getPlacePredictions({ input: term }, (results, status) => {
          if (status == google.maps.places.PlacesServiceStatus.OK) {
            observer.next(results.map(result => result.description));
            observer.complete();
          } else {
            console.log('Error - ', results, ' & Status - ', status);
            observer.next({});
            observer.complete();
          }
        });
    });
}

在控制器端,我的代码如下所示:

search = (text$: Observable<string>) =>
    text$
        .debounceTime(300)
        .distinctUntilChanged()
        .switchMap(term =>
            this.service.search(term)
                .do(() => this.searchFailed = false)
                .catch(() => {
                    this.searchFailed = true;
                    return Observable.of([]);
                }))

这很好用,但由于某些原因,输入提示栏出现在错误的位置,直到触发重绘。

Note the gap between the input field and the typeahead on the top image

按任意键或单击屏幕上的任意位置可立即更正它,但我不知道如何在第一时间更正它。

根据我的研究,似乎这可能是 NgZone 之外的 Google 地图位置自动完成服务 运行 的问题并且没有触发重绘,但我没有运气任何手动强制重绘的常用策略(ApplicationRef.tick()、NgZone.run()、ChangeDetectorRef.detectChanges())。

如有任何建议,我们将不胜感激!

编辑:具有类似行为的 Plunker: https://embed.plnkr.co/iy2Zhd5rEhBK2aVbBqsB/

我明白了! NgZone 最终成功了,但我不得不将它 放在 回调中,而不是包装它。

search(term: string) {
  if (term === '') {
    return Observable.of([]);
  }

  let result = Observable.create(observer => {
    this.autocompleteService.getPlacePredictions({ input: term }, (results, status) => {
      this.ngZone.run(() => {
        if (status == google.maps.places.PlacesServiceStatus.OK) {
          observer.next(results.map(result => result.description));
          observer.complete();
        } else {
          console.log('Error - ', results, ' & Status - ', status);
          observer.next({});
          observer.complete();
        }
      });
    });
  });
  return result;
}