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 应用程序结合使用,以便利用已经编写和测试的代码并改善性能。
[顶部]