Angular2 - ngZone - google.maps does not trigger change detection

I use the geocoding API, and when the results are returned, two-way data binding does not work. The data is simply not updated inside the view. If I change any other property manually, the data will be updated ... So, I googled (a lot) and found a solution that uses ngZone. Here is what I did:

  getLocation(address: string): void {
    var mygc = new google.maps.Geocoder();
    this._ngZone.runOutsideAngular(() => {

      mygc.geocode({
        'address': address
      }, (results, status) => {

        var data: any = results[0];

        this._ngZone.run(() => {
          this.myObject.myData = {          
            lat: data.geometry.location.lat(),
            lng: data.geometry.location.lng()
          };
        });

      });

    });
  }

So, I have a few questions:

  • When is it used ngZone? The documentation is pretty free ...
  • since it works without runOutsideAngular(), what's the point of using it? The example also includes this function call, so I also implemented it. But he works without him ...
  • Is there any other way to refresh myObjectin a view?

Thank!

+2
2

- , , , , script , zone.js. , script . Google . ....

, , ngZone.run.

- , , - , runOutsideAngular. , .

, , , Angular. runOutsideAngular, Angular run.

, , , -two- way (ngModel). , , . , ngZone.run. , changeRef.detectChanges , ApplicationRef tick(). data goes down, events go up.

constructor(private appRef: ApplicationRef){}

getLocation(address: string): void {
  let mygc = new google.maps.Geocoder();

  mygc.geocode({
    'address': address
  }, (results, status) => {

      let data: any = results[0];

      this.myObject.myData = {          
         lat: data.geometry.location.lat(),
         lng: data.geometry.location.lng()
      };

      this.appRef.tick();
  });
}

, , , ngZone.run. , , , google.maps events/addEventListener. , zone.js, Angular, .

, , ngZone.run, ApplicationRef.tick. , ngZone.run , () Angular, .

"" NgZone api

+4

:

  import { NgZone } from '@angular/core';

  constructor(
    private zone: NgZone
  ) { super(); }


 getLocation(address: string): void {
  var mygc = new google.maps.Geocoder();
  var self = this;

  mygc.geocode({
    'address': address
  }, (results, status) => {

    var data: any = results[0];

    self.zone.run(() => {
      self.myObject.myData = {          
        lat: data.geometry.location.lat(),
        lng: data.geometry.location.lng()
      };
    });
});
+1

Source: https://habr.com/ru/post/1670730/


All Articles