Bing 地圖服務路線最佳化程式範例中 JavaScript 和 C++ 之間的交互作業
Bing 地圖服務路線最佳化程式可使用 JavaScript 定義 UI 與 C++,以執行旅程最佳化。本文件說明 Bing 地圖服務路線最佳化程式範例的 JavaScript 和 C++ 組件如何相互操作。文中說明 JavaScript 元件如何初始化 C++ 元件並將資料傳送給它,以及 C++元件如何將資料傳回給 JavaScript 元件。JavaScript 和 C++ 元件在在 Bing 地圖服務路線最佳化程式範例中使用 JavaScript 和在 Bing 地圖服務路線最佳化程式範例中使用 C++ 文件中有詳細說明。
注意事項 |
---|
提醒您,我們將 default.html、default.css 與 default.js 統稱為「本機內容」(Local Context),因為這些檔案雖然可參考 Windows 執行階段 (其中包括自訂 C++ Windows 執行階段元件),但卻無法存取 Web。我們將 web.html、web.css 與 web.js 統稱為「Web 內容」(Web Context),因為這些檔案雖然可存取 Web,卻無法存取 Windows 執行階段。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();
}
Windows 執行階段可找出 TripOptimizer 物件並加以載入,因為 JavaScript Visual Studio 專案中包含 C++ 專案的參考。
[頂端]
將資料傳送至 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 方法會以 TripOptimizer.optimizerTripAsync 的形式公開至 JavaScript (第一個字母會變更為小寫,以符合標準 JavaScript 命名慣例)。 |
[頂端]
從 C++ 元件接收資料
C++ 元件中的 TripOptimizer::OptimizerTripAsync 方法會以非同步方式運作。因此,應用程式的 JavaScript 組件必須能夠在資料可用時加以處理。在非同步作業完成、擲回錯誤或報告進度時,JavaScript 組件可使用「承諾」(Promises) 來回應。下列範例說明 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);
}
}
asyncOperation = null;
},
function (error) {
if (error.description === "Canceled") {
canceledCallback();
}
else {
errorCallback("Error: " + error.message);
}
asyncOperation = null;
},
function (progress) {
progressCallback(progress);
}
);
}
請注意,當使用者選擇 [取消] 時,C++ 元件即會取消目前的作業。執行階段會為該作業呼叫錯誤處理常式。它會將錯誤的 description 欄位設定為「已取消」,以指出這是取消所造成的結果。如需如何以 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 移轉
如需如何從 ActiveX 版本的 Bing 地圖服務路線最佳化程式移轉至 Windows 市集應用程式的詳細資訊,請參閱在 Bing 地圖服務路線最佳化程式範例中移轉現有程式碼。
[頂端]
後續步驟
本文說明我們如何使用 JavaScript 與 C++ 建立完整的 Windows 市集應用程式。您可以考慮搭配使用 C++ 元件與 JavaScript 應用程式,讓您已撰寫並測試的程式碼充分發揮功效,並提升效能。
[頂端]