如何等待 BingMaps 在 Aurelia 中加载
How to wait BingMaps to be loaded in Aurelia
我正在尝试在 Aurelia SPA 中使用 BingMaps。
我所做的是将 BingMaps 脚本标记添加到索引页面的标题部分。像这样:
<head>
<meta charset="utf-8">
<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?branch=release'></script>
</head>
然后我有一个像这样的地图模板和地图控制器:
map.html
<template>
<div id='mainMap' style='width: 100vw; height: 100vh;'></div>
</template>
map.ts
export class Map
{
map:Microsoft.Maps.Map;
attached(){
this.map = new Microsoft.Maps.Map('#mainMap', {credentials: myKey});
this.map.setView({center: new Microsoft.Maps.Location(45.093,14.114), zoom:15});
}
}
现在,我正在为我的应用程序使用 Aurelia Typescript WebPack Skeleton。
如果我 运行 应用程序并单击地图菜单 link 我创建的所有内容都可以正常工作并且我显示了地图。
但是如果我在浏览器中按下 Refresh,Aurelia 会抛出一个异常:
Unhandled rejection TypeError: Cannot read property 'prototype' of null
at k (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:7096)
at h (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:6285)
at e (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:1106)
at t.l [as instance] (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:161)
at h (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:6042)
at e (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:1106)
at t.l [as instance] (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:161)
at new Microsoft.Maps.Map (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:13:4304)
at Map.attached (http://localhost:9000/app.bundle.js:28421:20)
at Controller.attached
好像在地图控制器中的Attached方法之前没有加载地图脚本是运行。
我如何告诉 Aurelia 在 运行 附加方法之前等待地图脚本加载?
你有两个选择。第一个是向地图脚本添加回调参数 URL 并传入函数名称以在加载地图脚本时调用。例如:
<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?callback=LoadMap' async defer></script>
请注意,您无需声明要发布分支,这是地图控件加载的默认分支。
第二个选项有点乱,但帮助了其他不想使用回调方法的人。此方法包括监视 Microsoft.Maps 命名空间并等待它可用。这可以使用超时来完成。例如:
function LoadMap(){
if(typeof Microsoft !== undefined && typeof Microsoft.Maps !== undefined){
//Map API available add your map load code.
} else {
setTimeout(LoadMap, 100);
}
}
你需要等待两个事件,第一个当然是脚本的加载,然后你需要等待微软脚本加载它的 API,为此存在回调参数:我建议第一个任务使用 jquery,因为它很容易转换为承诺,即:
const _BING_MAPS_URL = 'https//www.bing.com/api/maps/mapcontrol?';
const _DEFAULT_CONFIG = $.params({
key: 'yourkey',
callback: 'globalScopedCallback'
});
loadBingMaps() {
const callbackInvoked = new Promise((resolve) => {
window.globalScopedCallback = resolve;
});
const scriptLoaded = new Promise((resolve, reject) => {
$.getScript(_BING_MAPS_URL + _DEFAULT_CONFIG).done(resolve).fail(reject);
});
// You can add here more promises loading modules, and anything you need.
return Promise.all([callbackInvoked, scriptLoaded]);
}
// Now you are sure everything is loaded
loadBingMaps().then(doYourAwesomeStuff);
我正在尝试在 Aurelia SPA 中使用 BingMaps。 我所做的是将 BingMaps 脚本标记添加到索引页面的标题部分。像这样:
<head>
<meta charset="utf-8">
<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?branch=release'></script>
</head>
然后我有一个像这样的地图模板和地图控制器:
map.html
<template>
<div id='mainMap' style='width: 100vw; height: 100vh;'></div>
</template>
map.ts
export class Map
{
map:Microsoft.Maps.Map;
attached(){
this.map = new Microsoft.Maps.Map('#mainMap', {credentials: myKey});
this.map.setView({center: new Microsoft.Maps.Location(45.093,14.114), zoom:15});
}
}
现在,我正在为我的应用程序使用 Aurelia Typescript WebPack Skeleton。 如果我 运行 应用程序并单击地图菜单 link 我创建的所有内容都可以正常工作并且我显示了地图。 但是如果我在浏览器中按下 Refresh,Aurelia 会抛出一个异常:
Unhandled rejection TypeError: Cannot read property 'prototype' of null at k (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:7096) at h (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:6285) at e (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:1106) at t.l [as instance] (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:161) at h (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:6042) at e (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:1106) at t.l [as instance] (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:11:161) at new Microsoft.Maps.Map (https://www.bing.com/mapspreview/sdk/mapcontrol?branch=release:13:4304) at Map.attached (http://localhost:9000/app.bundle.js:28421:20) at Controller.attached
好像在地图控制器中的Attached方法之前没有加载地图脚本是运行。 我如何告诉 Aurelia 在 运行 附加方法之前等待地图脚本加载?
你有两个选择。第一个是向地图脚本添加回调参数 URL 并传入函数名称以在加载地图脚本时调用。例如:
<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?callback=LoadMap' async defer></script>
请注意,您无需声明要发布分支,这是地图控件加载的默认分支。
第二个选项有点乱,但帮助了其他不想使用回调方法的人。此方法包括监视 Microsoft.Maps 命名空间并等待它可用。这可以使用超时来完成。例如:
function LoadMap(){
if(typeof Microsoft !== undefined && typeof Microsoft.Maps !== undefined){
//Map API available add your map load code.
} else {
setTimeout(LoadMap, 100);
}
}
你需要等待两个事件,第一个当然是脚本的加载,然后你需要等待微软脚本加载它的 API,为此存在回调参数:我建议第一个任务使用 jquery,因为它很容易转换为承诺,即:
const _BING_MAPS_URL = 'https//www.bing.com/api/maps/mapcontrol?';
const _DEFAULT_CONFIG = $.params({
key: 'yourkey',
callback: 'globalScopedCallback'
});
loadBingMaps() {
const callbackInvoked = new Promise((resolve) => {
window.globalScopedCallback = resolve;
});
const scriptLoaded = new Promise((resolve, reject) => {
$.getScript(_BING_MAPS_URL + _DEFAULT_CONFIG).done(resolve).fail(reject);
});
// You can add here more promises loading modules, and anything you need.
return Promise.all([callbackInvoked, scriptLoaded]);
}
// Now you are sure everything is loaded
loadBingMaps().then(doYourAwesomeStuff);