У меня есть MEAN-приложение, использующее Angular и google.maps.Geocoder () из API Карт Google.Он показывает карту и может искать / визуализировать адреса.Я делаю это в компоненте «карта», и все работает.У меня есть дочерний компонент формы, который показывает результаты.Однако требуется несколько секунд (иногда до 20), чтобы компонент формы обнаружил изменения и отобразил их.Как так?
Возможная причина:
Возможно, основной поток JS занят моим запросом, блокируя обновление дочернего компонента.В сетевом журнале браузера я вижу файл с именем «websocket» (я думаю, что аналогичный создается при поиске) с «Ожиданием» времени и предупреждением «запрос еще не завершен».Интересно, почему это блокирует Angular (в частности, обновление дочернего компонента) и как этого избежать.
Подробнее:
Родитель и ребенок общаются через привязку ввода, и я также использую ngOnChanges для обмена данными.Для простоты у меня есть тест, в котором я просто перехожу из карты (родительский компонент) в форму (дочерний компонент) логического значения "formBoolean".Логическое значение отображается в форме после поиска по геокодированию, но, как уже было сказано, до того, как это произойдет, потребуется несколько секунд.
Примечание: когда я удаляю геокодирование из обратного вызова findLocation (), дочерний компонент быстро показывает изменения в логическом значении.Вот почему я думаю, что геокодирование "делает угол медленным"
Мой упрощенный код, показанный ниже, должен проиллюстрировать проблему.
index.html указывает на maps.googleapis.com с моим ключом API (не показан).
map.component.ts (родительский компонент):
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ViewChild } from '@angular/core';
@Component({
selector: 'app-map',
templateUrl: './map.component.html',
styleUrls: ['./map.component.css']
})
export class MapComponent implements OnInit {
ngOnInit() {
//Here I omit mapProp in the call to Map() above
this.map = new google.maps.Map(this.gmapElement.nativeElement);
}
@ViewChild('gmap') gmapElement: any;
map: google.maps.Map;
geocoder: any;
formChanged: boolean = false;
findLocation() {
if (!this.geocoder) this.geocoder = new google.maps.Geocoder();
this.geocoder.geocode({
'address': '1116 S Long Beach Blvd, Compton, CA 90221, USA',
'componentRestrictions': {country: 'US'} //I use country restriction
}, (results, status) => {
//I omit how I manipulate the results object, place a marker on the map, and pass data to child.
//The marker on the map appears immediately. I can console.log results
//For this example I just pass to the form component the followin boolean:
this.formChanged = !this.formChanged;
}
}
map.component.html (родительский компонент):
<!--For simplicity i just show the button and the binding to the child component-->
<button type="submit" class="btn btn-primary" (click)="findLocation()">Search</button>
<app-form [formChanged]="formChanged" [formResult]="formResult"></app-form>
form.component.ts (дочерний компонент):
import { Component, Input } from '@angular/core';
import { OnChanges, SimpleChanges, SimpleChange } from '@angular/core';
@Component({
selector: 'app-form',
templateUrl: '{{formChanged}}',
styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit, OnChanges {
@Input('formResult') formResult: Store;
@Input('formChanged') formChanged: boolean;
constructor(private storeService: StoreService){}
ngOnChanges(changes: SimpleChanges){
console.log('form - ngOnChanges',changes)
}
}
Как уже говорилось, геокодирование работает, но может пройти 20 секунд, прежде чем дочерний компонент "формы" будет обновлен, и я вижу изменения в консоли