2016-12-24 3 views
1

Angular2 + GMaps API에서이 문제가 발생합니다. 지도가로드되어 일부 마커를 설정하는 동안 스피너 프리 로더를 표시하려고합니다. addListenerOnce IDLE 리스너를 사용할 때 첫 번째 호출에서 리스너는 내 범위를 제어하고 내 구성 요소의 "this"변수는지도 자체로 바뀝니다. 예를 들어 리스너 내부에서 일부 함수 나 콜백을 실행하려고 할 때 내가 좋아하는 뭔가를 작성하는 경우 : 리스너에Angular2 + Google Maps API Idle 이벤트 리스너 문제

public isLoaded: boolean = false; 
... 
google.maps.event.addListener(map, 'idle',() => { 
this.isLoaded= true; 
}); 

변수 본을 따라서 undefined를 반환을 this.isLoaded, 구글 맵 자체에 변 (그게 전부가 구성 요소 범위를 참조해야합니다) (IsLoaded 표시 내 구성 요소의 속성입니다 지도 속성이 아님). 청취자가 내 구성 요소 범위를 제어하는 ​​것과 같습니다.

이상한 일은 구성 요소가 처음로드 될 때 한 번 발생하고 문제가 해결되고 모든 것이 올바르게 작동한다는 것입니다.

모든 솔루션? 내 영어로 미안해. 미리 감사드립니다. 함수를 실행하여 조각의 맥락에서

답변

1

(이, 인수)는 이러한 목적 함수는 .bind 않았습니다 또한, 명시 적으로 컨텍스트를 설정해야합니다 귀하의 경우에 따라서

이 callback.apply 같은 Gmaps에 의해 명시 적으로 설정 (그것은 여전히 ​​작동하지 않습니다) 방법 (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind)

public isLoaded: boolean = false; 
... 

const myCallback =() => { 
this.isLoaded= true; 
}; 

google.maps.event.addListener(map, 'idle',myCallback.bind(this)); 
+0

감사합니다. 그러나 작동하지 않았습니다. –

+0

괜찮습니다. 이전 해결책을 사용해보십시오.이 말을 참고하여 변수 콜백을 선언하십시오. const self = this; google.maps.event.addListener (map, 'idle',() => { self.isLoaded = true; }); –

+0

도 작동하지 않았습니다. 이 후 내가 만든 게시물을 확인해 주시겠습니까? Thnks –

0

.

console.log("THIS OUTSIDE listener callback:", this) 
     google.maps.event.addListenerOnce(this.map, 'idle', function() { 
      this.loaded = true; 
      console.log("THIS INSIDE listener callback:", this) 
     }.bind(this)); 

콘솔 출력은 다음과 같습니다 : 그래서

"THIS OUTSIDE listener callback: MapaComponent {loaded: false, latitude: 31.7413, longitude: -60.5115, bounds: _.ae, zoom: 12…}" 
"THIS INSIDE listener callback: MapaComponent {loaded: true, latitude: -31.7413, longitude: -60.5115, bounds: _.ae, zoom: 12…}" 

... 내가 추측 글쎄, 난 종류의이 같은 내 콜백 .bind (이)를 추가하여 범위 문제를 해결할 생각 범위 문제가 해결되었습니다. 그러나 내 스피너는 숨겨져 있지 않으며 페이지가로드 될 때 내지도를 볼 수 없습니다. 내 앱에서 다른 페이지로 이동 한 다음 내지도 페이지로 돌아 가면 회 전자가 숨기고 모든 것이 정상적으로 작동합니다. 내 구성 요소 코드 (요약) :

import { Component, OnInit } from '@angular/core'; 

@Component({ 
    selector: 'mapa-global', 
    template: ` 
    <div class="container" [hidden]="loaded"> 
     <div class="preloader-wrapper active" id="loader"> 
      <div class="spinner-layer spinner-red-only"> 
      <div class="circle-clipper left"> 
       <div class="circle"></div> 
      </div><div class="gap-patch"> 
       <div class="circle"></div> 
      </div><div class="circle-clipper right"> 
       <div class="circle"></div> 
       </div> 
      </div> 
     </div> 
     </div> 

    <div id="map-canvas-container" [hidden]="!loaded"> 
     <div id="map-canvas"></div> 
    </div> 
    `, 
    styleUrls: ['./mapa.component.css'] 
}) 
export class MapaComponent implements OnInit { 

    public loaded: boolean = false; 
    private latitude: number = -31.7413; 
    private longitude: number = -60.5115; 
    private bounds: any = new google.maps.LatLngBounds(); 
    private zoom: number = 12; 
    map: any; 

    ngOnInit() { this.initMap(); } 

    initMap() { 
     this.map = new google.maps.Map(document.getElementById('map-canvas'), { 
      center: { lat: this.latitude, lng: this.longitude }, 
      zoom: this.zoom 
     }); 

     console.log("THIS OUTSIDE listener callback:", this) 
     google.maps.event.addListenerOnce(this.map, 'idle', function() { 
      this.loaded = true; 
      console.log("THIS INSIDE listener callback:", this) 
     }.bind(this)); 
    } 
} 

의견이 있으십니까? 어쩌면 [숨겨진] 지시문이 잘못된 방식으로 구현되었을 수 있습니까?

1

Valikhan Akhmedov에게 감사드립니다. GMap 프리 로더가 작동 중입니다! 최종 솔루션 :

... 

constructor(private _detector: ChangeDetectorRef){} 

    ngOnInit() { this.initMap(); } 

    initMap() { 
     this.map = new google.maps.Map(document.getElementById('map-canvas'), { 
      center: { lat: this.latitude, lng: this.longitude }, 
      zoom: this.zoom 
     }); 

     google.maps.event.addListenerOnce(this.map, 'idle', function() { 
      this.loaded = true; 
      this._detector.detectChanges(); 
      google.maps.event.trigger(this.map,'resize'); 
      this.map.setCenter({ lat: this.latitude, lng: this.longitude });   
     }.bind(this)); 
    }