在 Bing 地图行程优化器示例中使用 JavaScript

Bing 地图行程优化器的 HTML 和 JavaScript 部分定义用户界面。该 UI 从用户那里收集位置并在 Bing 地图 AJAX 控件中显示所有位置中最短的路线。本文档介绍该应用程序中 JavaScript 部分的组织方式以及本地上下文和 Web 上下文相互进行通信的方式,还介绍了一些要记住的重要迁移点。

JavaScript 部分使用标准 CSS、HTML 和 JavaScript 来定义 UI。本文档不详细解释这些元素,但其中介绍了使 JavaScript Web 应用程序与 JavaScript Windows 应用商店 应用程序产生区别的元素。

备注

Bing 地图行程优化器示例中提供了与本文档对应的示例代码。

本文内容

  • 本地上下文和 Web 上下文

  • 从本地上下文中引用 Web 上下文

  • 上下文之间的通信

  • 从 ActiveX 中迁移

  • 后续步骤

本地上下文和 Web 上下文

使用 JavaScript 的 Windows 应用商店 应用程序包含至少一个 HTML 页。该页以及您在该应用程序自身中包含的其他任何页,通常在该应用程序的本地上下文中运行。当您使用 iframe 导航到远程页时,该页在 Web 上下文中运行并对您的系统具有有限的访问权限。有关在本地和 Web 上下文中可用于页面的不同限制和功能的详细信息,请参见Features and restrictions by context

Bing 地图行程优化器将 UI 分离到两对 HTML、CSS 和 JavaScript 文件中。我们认为,将引用 Windows 运行时 的代码与引用 Web 的代码分隔开来将使该应用程序更易于维护。文件 default.html、default.css 和 default.js 引用 Windows 运行时(其中包括自定义 C++ Windows 运行时 组件),但不访问 Web。default.html、default.css 和 default.js 表示应用程序的主页。文件 web.html,web.css 和 web.js 访问 Web,但不访问 Windows 运行时。web.html 的内容是本地上下文的嵌入式框架。

下图显示本地上下文与 Web 上下文之间的关系。本文档稍后将讨论这两个上下文之间如何通信。

本地上下文和 Web 上下文

安全说明安全说明

在单独模块中维护 Web 代码还有助于提高应用程序的安全性。如果可能,请验证在本地上下文接收的来自 Web 上下文的数据,以便最大限度地减少出现安全漏洞(例如缓冲区溢出)的机会。

[顶部]

从本地上下文中引用 Web 上下文

本地上下文 (default.html) 的 body 标记定义可保存 Web 上下文 (web.html) 的嵌入式框架 (iframe) 标记。

<iframe id="mapFrame" src="ms-appx-web:///html/web.html" style="position: absolute; left: 0px; width: 100%; top: 0px; height: 100%; overflow: hidden"></iframe>

当你在 JavaScript Windows 应用商店应用程序中引用代码文件时,使用以下语法非常重要:

src="ms-appx-web://<package-name>/<file-name>"

如果目标文件与调用文件属于同一个包,则可省略 <package-name> 部分。可在应用程序清单中找到包名称。若要执行此操作,请在 Visual Studio 中打开 package.appxmanifest 文件并选择**“打包”**选项卡。有关用 JavaScript 编写的 Windows 应用商店应用程序中新增导航功能的详细信息,请参见Quickstart: Using single-page navigation

[顶部]

上下文之间的通信

本地上下文和 Web 上下文使用跨文档消息进行通信。在上下文可以通信之前,它们必须先注册消息事件。default.html 和 web.html 都为 body 标记的 onload 属性指定一个 onLoad 函数。两个 onLoad 函数都调用 addEventListener 方法来侦听 message 类型的事件,并将这些消息路由到 receiveMessage 函数。以下示例显示用于本地上下文的 onLoad 函数。

function onLoad() {
    "use strict";
    window.addEventListener("message", receiveMessage, false);
}

重要

由于一个上下文不能直接访问另一个上下文的 DOM,因此 Bing 地图行程优化器使用跨文档消息。

上下文注册消息事件后可以使用 postMessage 方法进行通信。此方法可发送跨文档信息,该消息将路由到另一个上下文的消息事件处理程序,即 receiveMessage 函数。由于跨文档消息是基于文本的,因此该应用程序和 Web 上下文使用 JSON.stringify 函数将消息序列化为 JSON 文本。当上下文收到消息时,它将调用 JSON.parse 函数从 JSON 文本中反序列化字段。

阐明上下文之间的通信方式时,可考虑 Web 上下文是如何与本地上下文通信以初始化自定义 C++ Windows 运行时 组件的。(回想一下,Web 上下文不能直接与 Windows 运行时 组件交互)。在 Web 上下文 web.js 中定义的 onLoad 函数会在初始化期间调用。

web.js

// Called when the page loads.
function onLoad() {
    "use strict";
    // Hook to main frame for incoming messages.
    window.addEventListener("message", receiveMessage, false);

    // Disable input.
    disableElement(inputArea, true);

    // Load the C++ component.
    optimizerLoad();

    // Load a default map.
    map = new Microsoft.Maps.Map(document.getElementById("mapDiv"),
        {
            center: new Microsoft.Maps.Location(45.5, -80.5),
            mapTypeId: Microsoft.Maps.MapTypeId.auto,
            zoom: 4
        });

    // Reset waypoints.
    resetWaypoints();
}

onLoad 函数调用 optimizerLoad 函数。optimizerLoad 函数与本地上下文通信以初始化 C++ Windows 运行时组件。

web.js

function optimizerLoad() {
    "use strict";
    var message = { "invoke": "load" };
    window.parent.postMessage(JSON.stringify(message), "*");
}

我们从 Web 上下文而不是直接从本地上下文中启动 Windows 运行时组件的加载,以确保在创建 Windows 运行时组件之前两个上下文均已加载。

本地上下文中的 receiveMessage 函数分析消息并将调用路由到适当的消息处理程序。在此示例中,反序列化的 JavaScript 对象的 invoke 字段是“load”;因此,本地上下文调用 optimizerLoad 函数。

default.js

function receiveMessage(message) {
    "use strict";
    // Verify event origin.
    if (message.origin !== "ms-appx-web://microsoft.sdksamples.tripoptimizer.js") {
        return;
    }

    var data = JSON.parse(message.data);
    if (data.invoke === "load") {
        optimizerLoad();
    } else if (data.invoke === "optimizeTrip") {
        optimizerOptimizeTrip(
            data.locations,
            data.travelMode,
            data.optimize,
            data.bingMapsKey,
            data.alpha,
            data.beta,
            data.rho,
            data.iterations,
            data.parallel);
    } else if (data.invoke === "cancel") {
        optimizerCancel();
    } else if (data.invoke === "alert") {
            // Show message dialog.            
            new Windows.UI.Popups.MessageDialog(data.message).showAsync().then();
    }
}

在 Bing 地图行程优化器示例中的 JavaScript 和 C++ 之间进行互操作中解释了本地上下文中的 optimizerLoad 函数的详细信息。

[顶部]

从 ActiveX 中迁移

有关如何从 Bing 地图行程优化器的 ActiveX 版本迁移到 Windows 应用商店应用程序的信息,请参见在 Bing 地图行程优化器示例中迁移现有代码

[顶部]

后续步骤

阅读在 Bing 地图行程优化器示例中使用 C++以了解 Bing 地图行程优化器如何使用 C++ 执行计算密集型操作并因此改进整体性能。

[顶部]

请参见

其他资源

Create your first Windows Store app using JavaScript