Angular2 + Google Maps API空闲事件侦听器问题

时间:2016-12-24 23:31:40

标签: google-maps angular scope spinner preloader

我在使用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属性中的属性)。就像监听器控制我的组件范围一样,

奇怪的是,这会发生一次,当组件第一次加载时,它会修复并且一切正常。

任何解决方案?对不起我的英语不好。 提前谢谢!

3 个答案:

答案 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]指令以错误的方式实现?