如何在Angular2中异步加载google maps api

Dow*_*ski 17 google-maps angular

通常在一个普通的javascript网站上,我可以使用以下脚本来引用google maps api并设置该callback功能initMap.

<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>

我观察到的是initMap在普通的JavaScript网站正在窗口范围功能,它可以在脚本参数设置中引用- ?callback=initMap,但有一次我写angular2一个名为组件方法组件initMap,该initMap会的范围之内我的组件.然后我在索引中设置的异步加载脚本将无法捕获我的组件initMap方法.

具体来说,我想知道如何实现同样的目标Angular2

PS:我知道有一个angular2-google-maps组件可用于alphavia npm,但目前它的功能有限,所以我想知道如何在不使用其他组件的情况下以更简单的方式加载它,这样我就可以使用google maps api来实现我的项目.

jef*_*eff 20

我看到你不想要另一个组件,但聚合物的组件与谷歌apis一起运作良好.我有使用聚合物youtube数据api的angular2代码.我有帮助设置它.这是让我开始的傻瓜.我认为hardpart正在设置回调,我相信你可以在没有聚合物的情况下做到这一点.该示例显示了棘手的部分角度服务用于挂钩所有内容.

    const url = 'https://apis.google.com/js/client.js?onload=__onGoogleLoaded'

    export class GoogleAPI {
      loadAPI: Promise<any>
      constructor(){
        this.loadAPI = new Promise((resolve) => {
          window['__onGoogleLoaded'] = (ev) => {
            console.log('gapi loaded')
            resolve(window.gapi);
          }
          this.loadScript()
        });
        
      }
      
      doSomethingGoogley(){
        return this.loadAPI.then((gapi) => {
          console.log(gapi);
        });
      }
      
      loadScript(){
        console.log('loading..')
        let node = document.createElement('script');
        node.src = url;
        node.type = 'text/javascript';
        document.getElementsByTagName('head')[0].appendChild(node);
        
      }
    }
Run Code Online (Sandbox Code Playgroud)


Sim*_*n H 9

我在尝试开发渐进式网络应用程序时遇到了这个问题,即有可能无法上网.代码示例中存在错误:onload在google maps脚本中应该是callback.所以我对user2467174的修改导致了

地图loader.service.ts

const url = 'http://maps.googleapis.com/maps/api/js?key=xxxxx&callback=__onGoogleLoaded';

@Injectable()
export class GoogleMapsLoader {
    private static promise;

    public static load() {
        // First time 'load' is called?
        if (!GoogleMapsLoader.promise) {

            // Make promise to load
            GoogleMapsLoader.promise = new Promise( resolve => {

                // Set callback for when google maps is loaded.
                window['__onGoogleLoaded'] = (ev) => {
                    resolve('google maps api loaded');
                };

                let node = document.createElement('script');
                node.src = url;
                node.type = 'text/javascript';
                document.getElementsByTagName('head')[0].appendChild(node);
            });
        }

        // Always return promise. When 'load' is called many times, the promise is already resolved.
        return GoogleMapsLoader.promise;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我有一个组件

import { GoogleMapsLoader } from './map/map-loader.service';
constructor() {

    GoogleMapsLoader.load()
    .then(res => {
        console.log('GoogleMapsLoader.load.then', res);
        this.mapReady = true;
    })
Run Code Online (Sandbox Code Playgroud)

还有一个模板

<app-map *ngIf='mapReady'></app-map>
Run Code Online (Sandbox Code Playgroud)

这样地图div只在网上放入dom.

然后在map.component.ts中我们可以等到组件放入DOM之后再加载地图本身.

ngOnInit() {
    if (typeof google !== 'undefined') {
        console.log('MapComponent.ngOnInit');
        this.loadMap();
    }
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ift 5

以防万一你想使它成为一个静态函数,它总是返回一个promise,但只获得api一次.

const url = 'https://maps.googleapis.com/maps/api/js?callback=__onGoogleMapsLoaded&ey=YOUR_API_KEY';

export class GoogleMapsLoader {
    private static promise;
    public static load() {

    // First time 'load' is called?
    if (!GoogleMapsLoader.promise) {

        // Make promise to load
        GoogleMapsLoader.promise = new Promise((resolve) => {

            // Set callback for when google maps is loaded.
            window['__onGoogleMapsLoaded'] = (ev) => {
                console.log('google maps api loaded');
                resolve(window['google']['maps']);
            };

            // Add script tag to load google maps, which then triggers the callback, which resolves the promise with windows.google.maps.
            console.log('loading..');
            let node = document.createElement('script');
            node.src = url;
            node.type = 'text/javascript';
            document.getElementsByTagName('head')[0].appendChild(node);
        });
    }

    // Always return promise. When 'load' is called many times, the promise is already resolved.
    return GoogleMapsLoader.promise;
}
Run Code Online (Sandbox Code Playgroud)

}

这是你如何在其他脚本中获取api:

GoogleMapsLoader.load()
            .then((_mapsApi) => {
                debugger;
                this.geocoder       = new _mapsApi.Geocoder();
                this.geocoderStatus = _mapsApi.GeocoderStatus;
            });
Run Code Online (Sandbox Code Playgroud)