1

我正在開發使用Ng-Bootstrap的typeahead directive的Angular 4應用程序。在維基百科示例中,他們對維基百科進行api調用,並將結果顯示在鍵入框中。我試圖做同樣的事情,而是使用Google地圖的自動填充服務。谷歌地圖地點自動完成的Ng-Bootstrap Typeahead不正確的樣式

繼維基百科示例之後,我創建了一個類似的服務,它返回一個包含自動完成位置的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/

+0

通常'NgZone.run()'應該有效。你能不能把一個重複這個問題的重擊者放在一起,以便我們看看? –

+0

你會在哪裏推薦做NgZone.run()? –

+0

在調用外部API(谷歌地圖)的地方。再次,有一個重現場景的蹲伏者會讓我們更快地得到答案:-) –

回答

0

我知道了! 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; 
}