Привязка свойства внутри AfterViewInit не влияет на представление - PullRequest
0 голосов
/ 17 июня 2020

Я работаю с Mapbox в моем проекте Angular, и мне нужно показать некоторую информацию в моем component.html из моего component.ts.

Я использую mat-vertical-stepper, где каждый step - новый component:

 <mat-vertical-stepper #stepper>
      ...
      <mat-step [stepControl]="locationStepForm">
           <ng-template matStepLabel>Localização</ng-template>
           <app-location-step [locationStepForm]="locationStepForm"></app-location-step>
      </mat-step>
      ...
 </mat-vertical-stepper>

Итак, внутри locationStepForm у меня есть карта Mapbox. Чтобы карта заработала, я помещаю ее инициализацию в метод AfterViewInit:

  @Input() locationStepForm: FormGroup;

  ngAfterViewInit() {
    const container = document.getElementById('map');

    if (container) {
      var map = new Mapboxgl.Map({
        container: this.map.nativeElement, // container id
        style: 'mapbox://styles/mapbox/streets-v11',
        center: [-51.186971, -29.1836891], // starting position, LNG/LAT
        zoom: 15 // starting zoom
      });
    }
  }

Проблема в том, что в какой-то момент мне нужно вызвать функцию для обновления свойства, чтобы его значение можно было отобразить в представление через привязку свойств.

  @Input() locationStepForm: FormGroup;

  latitude: number = 0;  

  ngAfterViewInit() {
    const container = document.getElementById('map');

    if (container) {
      var map = new Mapboxgl.Map({
        container: this.map.nativeElement, // container id
        style: 'mapbox://styles/mapbox/streets-v11',
        center: [-51.186971, -29.1836891], // starting position, LNG/LAT
        zoom: 15 // starting zoom
      });

      geocoder.on('result', function (e) {
         geocoder.clear();
         this.updateLatitude(e.result.center[1]);
      }
    }
  }

  updateLatitude(latitude: number) {
     this.latitude = latitude;
  }

Когда вызывается this.updateLatitude(e.result.center[1]);, я получаю эту ошибку:

enter image description here

И если Я обращаюсь к свойству напрямую, информация не отображается в моем component.html.

  ngAfterViewInit() {
    ...

    geocoder.on('result', function (e) {
        ...
        this.latitude = e.result.center[1];
    }
  }

И это мой компонент. html:

<form [formGroup]="locationStepForm">

    <p class="m-l-10">
        <span class="text-header">Informe a localização</span>
    </p>

    <div id="geocoder" class="geocoder"></div>
    <div #mapElement id="map" class="map"></div>

    <div>
        <p>
            <span class="text-header">Local selecionado</span>
        </p>

        <p>
            <span>Latitude: {{latitude}}</span>
        </p>

        <p>
            <span>Longitude: {{longitude}}</span>
        </p>
    </div>

    <div>
        <button mat-button matStepperPrevious>Retornar</button>
        <button mat-button matStepperNext class="button-colored m-l-10">Avançar</button>
    </div>
</form>

Есть идеи, что я делаю не так?

1 Ответ

2 голосов
/ 17 июня 2020

В этой части следует использовать стрелочную функцию:

  geocoder.on('result', (e) => { //here use arrow function
    geocoder.clear();
    this.updateLatitude(e.result.center[1]);
  }

Обратите внимание, что если вы используете function, ссылка на this уже не та. Если вы настаиваете на использовании function вместо arrow function, вам следует сохранить ссылку на this в переменной перед событием geocoder.on.

  ngAfterViewInit() {
    const container = document.getElementById('map');
    var self = this;

    if (container) {
      var map = new Mapboxgl.Map({
        container: this.map.nativeElement, // container id
        style: 'mapbox://styles/mapbox/streets-v11',
        center: [-51.186971, -29.1836891], // starting position, LNG/LAT
        zoom: 15 // starting zoom
      });

      geocoder.on('result', function (e) {
         geocoder.clear();
         self.updateLatitude(e.result.center[1]);
      }
    }
  }
...