如何等待 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);