通常在普通的javascript网站中,我可以使用以下脚本来引用google maps api,并将callback
函数设置为initMap
。
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
我观察到普通javascript网站中的initMap
函数位于窗口范围内,并且可以在脚本参数设置中引用 - ?callback=initMap
,但是一旦我在angular2中编写了一个组件使用名为initMap
的组件方法,initMap
将在我的组件范围内。然后我在索引中设置的异步加载脚本将无法捕获我的组件initMap
方法。
Angular2
中实现同样的目标?PS:我知道
angular2-google-maps
通过alpha
提供了npm
个组件,但目前它的功能有限,所以我想知道如何加载它以更简单的方式不使用其他组件,所以我可以使用谷歌地图api来实现我的项目。
答案 0 :(得分:19)
我看到你不想要另一个组件,但聚合物的组件可以与谷歌apis一起使用。我有使用聚合物youtube数据api的angular2代码。我有帮助设置它。这是让我入门的plunker。我认为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);
}
}
答案 1 :(得分:8)
我在尝试开发渐进式网络应用程序时遇到了这个问题,即有可能无法上网。代码示例中存在错误:Google地图脚本中的onload
应为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;
}
}
然后我有组件与
import { GoogleMapsLoader } from './map/map-loader.service';
constructor() {
GoogleMapsLoader.load()
.then(res => {
console.log('GoogleMapsLoader.load.then', res);
this.mapReady = true;
})
模板
<app-map *ngIf='mapReady'></app-map>
这样地图div只会在网上放入dom。
然后在 map.component.ts 中,我们可以等到组件放入DOM之后再加载地图本身。
ngOnInit() {
if (typeof google !== 'undefined') {
console.log('MapComponent.ngOnInit');
this.loadMap();
}
}
答案 2 :(得分: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;
}
}
这是你可以在其他脚本中获取api的方法:
GoogleMapsLoader.load()
.then((_mapsApi) => {
debugger;
this.geocoder = new _mapsApi.Geocoder();
this.geocoderStatus = _mapsApi.GeocoderStatus;
});
答案 3 :(得分:1)
这就是我目前正在使用的内容:
loadMapsScript(): Promise<void> {
return new Promise(resolve => {
if (document.querySelectorAll(`[src="${mapsScriptUrl}"]`).length) {
resolve();
} else {
document.body.appendChild(Object.assign(document.createElement('script'), {
type: 'text/javascript',
src: mapsScriptUrl,
onload: doMapInitLogic();
}));
}
});
}
请参阅我更全面的说明here