Condividi tramite


Interazione tra JavaScript e C++ nell'utilità di ottimizzazione dei viaggi di Bing Mappe

L'utilità di ottimizzazione dei viaggi di Bing Mappe utilizza JavaScript per definire l'interfaccia utente e C++ per eseguire l'ottimizzazione dei viaggi. In questo documento viene descritto come interagiscono le parti JavaScript e C++ dell'esempio dell'utilità di ottimizzazione dei viaggi di Bing Mappe. Viene descritto in che modo il componente JavaScript inizializza e invia dati al componente C++ e in che modo il componente C++ invia dati al componente JavaScript. I singoli componenti JavaScript e C++ vengono descritti più dettagliatamente nei documenti Utilizzo di JavaScript nell'esempio di utilità di ottimizzazione dei viaggi di Bing Mappe e Utilizzo di C++ nell'esempio di utilità di ottimizzazione dei viaggi di Bing Mappe.

Nota

Ricorda che facciamo riferimento ai file default.html, default.css e default.js come contesto locale perché essi possono fare riferimento a Windows Runtime, che include il componente C++ personalizzato di Windows Runtime, ma non possono accedere al Web. Facciamo riferimento ai file web.html, web.css e web.js come contesto Web perché questi file possono accedere al Web, ma non a Windows Runtime. Il contesto Web definisce anche l'interfaccia utente.

Nota

Il codice di esempio che corrisponde a questo documento è disponibile nella pagina relativa all'esempio di utilità di ottimizzazione dei viaggi di Bing Mappe.

In questo articolo

  • Inizializzazione del componente C++ da JavaScript

  • Invio di dati al componente C++

  • Ricezione di dati dal componente C++

  • Migrazione da ActiveX

  • Passaggi successivi

Inizializzazione del componente C++ da JavaScript

Il contesto locale dichiara variabili che rappresentano il componente C++ e l'operazione corrente di ottimizzazione dei viaggi.

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

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

La funzione optimizerLoad, chiamata durante l'inizializzazione dell'app, crea l'oggetto TripOptimizer.

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

Windows Runtime può individuare e caricare l'oggetto TripOptimizer poiché il progetto JavaScript di Visual Studio contiene un riferimento al progetto C++.

[All'inizio]

Invio di dati al componente C++

Nel documento Utilizzo di JavaScript nell'esempio di utilità di ottimizzazione dei viaggi di Bing Mappe viene descritta la modalità di comunicazione dei contesti locale e Web. Quando l'utente seleziona il pulsante Annulla o Ottieni indicazioni, il contesto Web invia un messaggio al contesto locale per chiamare il metodo TripOptimizer appropriato nel componente C++. Ad esempio, quando l'utente sceglie Ottieni indicazioni, il contesto Web invia la stringa "optimizeTrip" come parte del messaggio al contesto locale. Quando l'utente sceglie Annulla, il contesto Web invia la stringa "cancel". Nel codice seguente viene illustrato in che modo il contesto locale riceve questi messaggi dal 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();
    }
}

La funzione optimizerOptimizeTrip inoltra i parametri dal contesto Web al componente 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);

In questo esempio viene anche impostata la variabile asyncOperation. Impostiamo questa variabile in modo da poter annullare l'operazione quando l'utente sceglie Annulla.

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

Nota

Il metodo TripOptimizer::OptimizerTripAsync nel componente C++ è esposto a JavaScript come TripOptimizer.optimizerTripAsync (la prima lettera viene visualizzata in lettere minuscole per rispettare le convenzioni di denominazione JavaScript standard).

[All'inizio]

Ricezione di dati dal componente C++

Il metodo TripOptimizer::OptimizerTripAsync nel componente C++ funziona in modo asincrono. Pertanto, la parte JavaScript dell'app deve essere in grado di elaborare i dati quando diventano disponibili. La parte JavaScript utilizza i suggerimenti per rispondere al completamento di un'operazione asincrona, genera un errore o segnala lo stato. Nell'esempio seguente viene illustrato in che modo la funzione optimizerOptimizeTrip definisce i callback di completamento, errore e stato per la chiamata a 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);
        }
        );
}

Nota che quando l'utente sceglie Annulla, il componente C++ annulla l'operazione corrente. Il runtime chiama il gestore errori per l'operazione. Imposta il campo description dell'errore su "Annullato" per indicare che il risultato è dovuto all'annullamento. Per ulteriori informazioni su come utilizzare le operazioni asincrone in JavaScript, vedi Asynchronous programming.

Quando il contesto locale riceve lo stato o il risultato di un'operazione asincrona, inoltra i dati dell'evento al contesto Web in modo che possa aggiornare l'interfaccia utente. Ad esempio, la funzione progressCallback invia la stringa "progressCallback" come parte del messaggio inviato al contesto Web.

// 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), "*");
}

Nell'esempio seguente viene illustrata la funzione receiveMessage per il contesto Web. Questa funzione riceve messaggi dal contesto locale.

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

Per il messaggio "progressCallback", il contesto Web chiama la funzione progressCallback, che aggiorna l'interfaccia utente per visualizzare il messaggio di stato.

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

[All'inizio]

Migrazione da ActiveX

Per informazioni sulla modalità di migrazione dalla versione ActiveX dell'utilità di ottimizzazione dei viaggi di Bing Maps a un'app di Windows Store, vedi Migrazione del codice esistente nell'utilità di ottimizzazione dei viaggi di Bing Mappe.

[All'inizio]

Passaggi successivi

In questo articolo viene spiegato come abbiamo utilizzato JavaScript e C++ per creare un'app in Windows Store completa. Valuta l'utilizzo di un componente C++ con l'app JavaScript per sfruttare il codice già scritto e testato e migliorare le prestazioni.

[All'inizio]