在 Bing 地图行程优化器示例中的 JavaScript 和 C++ 之间进行互操作

Bing 地图行程优化器使用 JavaScript 定义 UI 和 C++ 来执行行程优化。本文档介绍 Bing 地图行程优化器示例的 JavaScript 和 C++ 部分如何交互操作。本文档还介绍 JavaScript 组件如何初始化 C++ 组件并向其发送数据,以及 C++ 组件如何将数据发送回 JavaScript 组件。文档在 Bing 地图行程优化器示例中使用 JavaScript在 Bing 地图行程优化器示例中使用 C++中更详细地介绍了各个 JavaScript 和 C++ 组件。

备注

回想一下,由于 default.html、default.css 和 default.js 可以引用 Windows 运行时(包括自定义 C++ Windows 运行时组件)但无法访问 Web,因此我们将这些文件称为本地上下文。由于 web.html、web.css 和 web.js 可以访问 Web 但无法访问 Windows 运行时,因此我们将这些文件称为 Web 上下文。Web 上下文还定义用户界面。

备注

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

本文内容

  • 从 JavaScript 中初始化 C++ 组件

  • 向 C++ 组件发送数据

  • 接收来自 C++ 组件的数据

  • 从 ActiveX 中迁移

  • 后续步骤

从 JavaScript 中初始化 C++ 组件

本地上下文用于声明表示 C++ 组件和当前行程优化操作的变量。

// The C++ component.
var tripOptimizer = null;

// The current asynchronous trip optimization.
var asyncOperation = null;

在应用程序初始化期间调用的 optimizerLoad 函数会创建 TripOptimizer 对象。

function optimizerLoad() {
    "use strict";
    tripOptimizer = new TripOptimizerComponent.TripOptimizer();
}

由于 JavaScript Visual Studio 项目包含对 C++ 项目的引用,因此 Windows 运行时可以查找和加载 TripOptimizer 对象。

[顶部]

向 C++ 组件发送数据

在 Bing 地图行程优化器示例中使用 JavaScript一文介绍 Web 上下文和本地上下文如何进行通信。当用户选择**“获取路线”“取消”按钮时,Web 上下文将向本地上下文发送一条消息,以便在 C++ 组件中调用相应的 TripOptimizer 方法。例如,当用户选择“获取路线”时,Web 上下文会将字符串“optimizeTrip”作为消息的一部分发送至本地上下文。当用户选择“取消”**时,Web 上下文将发送字符串“cancel”。以下代码演示本地上下文如何接收来自 Web 上下文中的这些消息。

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();
    }
}

optimizerOptimizeTrip 函数可将参数从 Web 上下文转发给 C++ 组件。

function optimizerOptimizeTrip(locations, travelMode, optimize, bingMapsKey, alpha, beta, rho, iterations, parallel) {
    "use strict";
    asyncOperation = tripOptimizer.optimizeTripAsync(locations, travelMode, optimize, bingMapsKey,
        alpha, beta, rho, iterations, parallel);

此示例还设置 asyncOperation 变量。我们设置此变量后,就可以在用户选择**“取消”**时取消操作。

function optimizerCancel() {
    "use strict";
    if (asyncOperation !== null) {
        asyncOperation.cancel();
    }
}

备注

C++ 组件中的 TripOptimizer::OptimizerTripAsync 方法向 JavaScript 公开为 TripOptimizer.optimizerTripAsync(第一个字母更改为小写,以匹配标准的 JavaScript 命名约定)。

[顶部]

接收来自 C++ 组件的数据

C++ 组件中的 TripOptimizer::OptimizerTripAsync 方法以异步方式执行操作。因此,该应用程序的 JavaScript 部分在可用时必须能够处理数据。当异步操作完成、引发错误或报告进度时,JavaScript 部分使用承诺来响应。以下示例演示 optimizerOptimizeTrip 函数如何为 TripOptimizer::OptimizeTripAsync 的调用定义完成、错误和进度回调。

function optimizerOptimizeTrip(locations, travelMode, optimize, bingMapsKey, alpha, beta, rho, iterations, parallel) {
    "use strict";
    asyncOperation = tripOptimizer.optimizeTripAsync(locations, travelMode, optimize, bingMapsKey,
        alpha, beta, rho, iterations, parallel);

    asyncOperation.then(
        function (result) {
            if (result !== null) {
                // If the result contains certain keys, then we know that the results contain
                // the optimize route.
                if (result.size === 2 && result.hasKey("locations") && result.hasKey("displayNames")) {
                    routeCallback(result);
                }
                    // Otherwise, we know that the component is asking us to resolve ambiguous locations.
                else {
                    locationsCallback(result);
                }
            }
            else {
                canceledCallback();
            }
            asyncOperation = null;
        },
        function (error) {
            if (error.description === "Canceled") {
                canceledCallback();
            }
            else {
                errorCallback("Error: " + error.message);
            }
            asyncOperation = null;
        },
        function (progress) {
            progressCallback(progress);
        }
        );
}

请注意,当用户选择**“取消”**时,C++ 组件会取消当前操作。运行时为操作调用错误处理程序。它将错误的 description 字段设置为“Canceled”,指示该结果是由取消引起的。有关在 JavaScript 中如何使用异步操作的详细信息,请参见Asynchronous programming

当本地上下文收到异步操作的进度或结果时,它会将事件数据转发给 Web 上下文,以便 Web 上下文能够更新 UI。例如,progressCallback 函数会在发送给 Web 上下文的消息中发送字符串“progressCallback”。

// Event handler for progress notifications from the Windows Runtime component.
function progressCallback(info) {
    "use strict";
    var message = { "invoke": "progressCallback", "message": info };
    window.parent.frames.mapFrame.postMessage(JSON.stringify(message), "*");
}

以下示例显示用于 Web 上下文的 receiveMessage 函数。此函数接收来自本地上下文的消息。

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

    var data = JSON.parse(message.data);
    if (data.invoke === "progressCallback") {
        progressCallback(data.message);
    } else if (data.invoke === "locationsCallback") {
        locationsCallback(JSON.parse(data.locationOptions));
    } else if (data.invoke === "routeCallback") {
        routeCallback(data.locations, data.displayNames);
    } else if (data.invoke === "canceledCallback") {
        canceledCallback();
    } else if (data.invoke === "errorCallback") {
        errorCallback(data.message);
    }
}

对于“progressCallback”消息,Web 上下文会调用 progressCallback 函数,该函数可更新 UI 以显示进度消息。

// Event handler for progress notifications from the control.
function progressCallback(message) {
    "use strict";
    // Set message.
    progressMessageText.innerHTML = message;
}

[顶部]

从 ActiveX 中迁移

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

[顶部]

后续步骤

本文说明了如何使用 JavaScript 和 C++ 创建完整的 Windows 应用商店应用程序。考虑将 C++ 组件与 JavaScript 应用程序结合使用,以便利用已经编写和测试的代码并改善性能。

[顶部]