маркеры на картах Google с помощью Angular 6 - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть список геолокаций в моей базе данных, и я храню их в такой переменной:

.ts

  ngOnInit() {
    this.getListings()
  }

  getListings() {
    this.serviceHomeScreen.getAllListingsDetails().subscribe((data) => {
      this.extractlistings(data[0])
    })
  }

  extractlistings(data) {
    this.locations = data

    console.log(this.locations[1]) // has the right value
  }

  mapReady(map) {
    console.log(this.locations[1]) // undefined

    for (let i = 0; i < this.locations.length; i++) {
      console.log("aici")
      new google.maps.Marker({
        position: { lat: this.locations[i].lat, lng: this.locations[i].long },
        map: map,
      });
    }
  }

.html

<agm-map id="map_" [zoom]="30" [fitBounds]="true" [latitude]="lat" [longitude]="lng" [streetViewControl]="false" [zoomControl]="false" (mapReady)="mapReady($event)"></agm-map>

где местоположения что-то вроде этого

locations = [{'id': 1, 'lat': '43', long: '-12'}, {'id': 2, 'lat': '34', long: '-15'}, {'id': 3, 'lat': '13', long: '-12'}]

Проблема в том, что я получаю этот массив locations из службы, он имеет правильное значение, но внутри функции mapReady(),когда мне нужны широта и долгота из массива, это undefined.

Почему это?mapReady вызывается раньше ngOnInit?

Спасибо за потраченное время!

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

mapReady(map) вызывается выходом, испускаемым компонентом <agm-map>, который может быть передан до завершения завершения ngOnInit(), поэтому вы получите undefined для this.locations.

Попробуйте получить ваши местоположения, когда карта будет готова, тогда вы не получите undefined.

mapReady(map) {

    this.serviceHomeScreen.getAllListingsDetails().subscribe((data) => {
        this.locations = data[0];

        for (let i = 0; i < this.locations.length; i++) {
            console.log("aici")
            return new google.maps.Marker({
                position: { lat: this.locations[i].lat, lng: this.locations[i].long },
                map: map,
            });
       }    
    })            
}

Другой подход заключается в том, чтобы продолжить получать данные на ngOnInit, но установить флаг, например this.dataLoaded = true когда данные закончили загрузку.Затем вы будете использовать это свойство в *ngIf в шаблоне компонента <agm-map>, чтобы компонент загружался только тогда, когда данные готовы.Затем данные будут доступны, когда (mapReady) отправляется и вызывается mapReady(map).

dataLoaded = false;

ngOnInit() {
    this.getListings()
}

getListings() {
    this.serviceHomeScreen.getAllListingsDetails().subscribe((data) => {
      this.extractlistings(data[0]);
    })
}

extractlistings(data) {
    this.locations = data;
    this.dataLoaded = true;
    console.log(this.locations[1]); // has the right value
}

mapReady(map) {

    console.log(this.locations[1]); // now defined

    for (let i = 0; i < this.locations.length; i++) {
        console.log("aici")
        return new google.maps.Marker({
            position: { lat: this.locations[i].lat, lng: this.locations[i].long },
                map: map,
        });
    }              
}

Шаблон:

<agm-map 
*ngIf="dataLoaded" 
id="map_" 
[zoom]="30" 
[fitBounds]="true" 
[latitude]="lat" 
[longitude]="lng" 
[streetViewControl]="false" 
[zoomControl]="false" 
(mapReady)="mapReady($event)">
</agm-map>
0 голосов
/ 27 февраля 2019

Не думаю, что проблема в том, что mapReady вызывается до ngOnInit, но больше того, что mapReady вызывается до того, как getAllListingsDetails возвращает значение.

Один из способов обойти ожидание готовности картыпоскольку вы используете angular-maps, это значит использовать директиву <agm-marker> внутри <agm-map>.

Например:

<agm-map>
            <agm-marker *ngFor="let m of markers; let i = index"
                        [latitude]="m.lat"
                        [longitude]="m.lng"
                        label="{{ i + 1 }}">
                <agm-info-window>
                    <strong>InfoWindow content</strong>
                </agm-info-window>
            </agm-marker>
</agm-map>
...