«Задержка» связана с обнаружением изменений, если вы щелкнете документ после ввода поиска местоположения, angular получит событие и обновит DOM.
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)))
);
}
Я также добавил несколько других улучшений:
Загрузка API API карт только один раз в конструктор, чтобы избежать уже загруженной ошибки (также, когда stackblitz приводит к загрузке службы несколько раз, поэтому я изменяю перезагрузкумеханизм на странице в левом нижнем меню):
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 карты, поэтому я добавил наблюдаемую загрузку, чтобы компонент знал, когда он может начать поиск.
Вот новый стек с изменениями.