Twitter bootstrap Ng Bootstrap Typeahead使用Google Maps Place Autocomplete时样式不正确

Twitter bootstrap Ng Bootstrap Typeahead使用Google Maps Place Autocomplete时样式不正确,twitter-bootstrap,angular,google-maps-api-3,rxjs,ng-bootstrap,Twitter Bootstrap,Angular,Google Maps Api 3,Rxjs,Ng Bootstrap,我正在开发一个Angular 4应用程序,它使用Ng引导功能。在Wikipedia示例中,他们对Wikipedia进行api调用,并在typeahead框中显示结果。我正试图做同样的事情,但与谷歌地图的位置自动完成服务 在Wikipedia示例之后,我创建了一个类似的服务,它返回一个包含自动完成位置的Rxjs可观测值 search(term: string) { if (term === '') { return Observable.of([]); } r

我正在开发一个Angular 4应用程序,它使用Ng引导功能。在Wikipedia示例中,他们对Wikipedia进行api调用,并在typeahead框中显示结果。我正试图做同样的事情,但与谷歌地图的位置自动完成服务

在Wikipedia示例之后,我创建了一个类似的服务,它返回一个包含自动完成位置的Rxjs可观测值

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([]);
                }))
search=(text$:Observable)=>
正文$
.debounceTime(300)
.distinctUntilChanged()
.switchMap(术语=>
this.service.search(术语)
.do(()=>this.searchFailed=false)
.catch(()=>{
this.searchFailed=true;
([])的可观测收益率;
}))
这很有效,但由于某些原因,typeahead栏出现在错误的位置,直到有东西触发重画

按任意键或点击屏幕上的任意位置都会立即纠正错误,但我不知道如何在第一时间纠正错误

根据我的研究,Google Maps place autocomplete服务在NgZone之外运行,并且没有触发重画,这似乎是一个问题,但我没有任何常用的策略手动强制重画(ApplicationRef.tick()、NgZone.run()、ChangeDetectorRef.detectChanges())

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

编辑:具有类似行为的Plunker:
我明白了!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;
}

正常情况下,
NgZone.run()
应该可以做到这一点。你能不能放一个plunker来重现这个问题,让我们看看?你建议在哪里做NgZone.run()?在一个调用外部API(谷歌地图)的地方。再一次,有一个带有复制场景的plunker会让我们更快地找到答案:-)所以我在plunker中得到了几乎完全相同的行为,除了typeahead在事件之前没有对齐之外,它只是在事件之前根本没有出现。尝试键入一个字符,等待一秒钟,然后按shift键之类的键。此时才显示“前方键入”。