我在使用Angular2 + GMaps API时遇到了这个问题。 我想在地图加载并设置一些标记时显示一个微调器预加载器。 当使用addListenerOnce IDLE Listener时,在第一次调用时,监听器控制我的作用域,我的组件中的变量“this”变成了映射本身,所以当我想在监听器中执行某些函数或回调时,例如,如果我写的话:
public isLoaded: boolean = false;
...
google.maps.event.addListener(map, 'idle', () => {
this.isLoaded= true;
});
变量THIS进入监听器(那应该引用Component范围)变成谷歌地图本身,因此this.isLoaded返回Undefined(isLoaded是我的Component not map属性中的属性)。就像监听器控制我的组件范围一样,
奇怪的是,这会发生一次,当组件第一次加载时,它会修复并且一切正常。
任何解决方案?对不起我的英语不好。 提前谢谢!
答案 0 :(得分:1)
在函数执行的代码段上下文中由Gmaps显式设置,例如callback.apply(this,args)
因此,对于您的情况,您只需要显式设置上下文,为此目的函数有.bind()方法(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));
答案 1 :(得分: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));
}
答案 2 :(得分:0)
它仍然无法运作。好吧,我认为我通过将.bind(this)添加到我的回调中来解决范围问题,如下所示:
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…}"
所以...我猜范围问题已经解决了。 但是我的微调器没有隐藏,加载页面时无法看到我的地图。 如果我导航到我的应用程序内的另一个页面,然后返回到我的地图页面,那么微调器隐藏,一切正常。 我的组件代码(汇总)是:
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));
}
}
有什么建议吗?也许[hidden]指令以错误的方式实现?