Condividi tramite


Il presente articolo è stato tradotto automaticamente.

Microsoft Office

Analisi dell'API JavaScript per Office: Associazione e Web part XML personalizzate

Stephen Oliver
Eric Schmidt

Scarica il codice di esempio

Questo articolo è la parte 3 in una serie di procedure dettagliate approfondita dell'API JavaScript per l'ufficio. Questo articolo prosegue l'esame degli aspetti chiavi dell'API, concentrandosi sull'associazione dati e il supporto per lavorare con Web part XML personalizzate. Parte 1, "Exploring the New JavaScript API per Office" (msdn.microsoft.com/magazine/jj891051), fornisce un'ampia panoramica del modello a oggetti. Parte 2, "esplorando l'API JavaScript per Office: Accesso ai dati e gli eventi"(msdn.microsoft.com/magazine/jj991976), guarda da vicino il concetto importante di come ottenere il contenuto del file e conduce una profonda revisione del modello di evento. A seguito di questo articolo, parte 4 si concentrerà esclusivamente sul terzo tipo di app per Office: applicazioni di posta elettronica.

Per tutta questa serie, facciamo spesso riferimento all'API JavaScript per la documentazione di riferimento per Office. Potete trovare la documentazione ufficiale, esempi di codice e risorse comunitarie presso le applicazioni per Office e SharePoint Developer Preview pagina su MSDN (dev.office.com).

Associazione dati in un App per ufficio

Associazione dati fornisce stretta integrazione tra le app e una regione specifica di dati nel documento. I dati della regione sono associati a un oggetto denominato nell'app così che l'applicazione può accedere ai dati della regione denominata, anche se l'utente ha selezionato qualcosa d'altro.

Una volta creato, l'associazione persiste anche se la regione è spostata nella pagina (in Word) o copiati in un altro foglio di lavoro (in Excel). Ad esempio, un collegamento a una tabella persiste anche se viene rinominato da parte dell'utente.

Quando i dati della regione sono cambiati, l'associazione genera un evento in cui può collegare l'app. Da questo evento, l'app può ottenere i dati che ha cambiato e reagire in modo appropriato.

Le associazioni e la "vista" di un App certamente, l'associazione di dati in un'applicazione per ufficio dà un'app accesso diretto a un set di dati all'interno del file di Office, rendendo così più facile per il app analizzare i dati senza fare affidamento sull'azione diretta da parte dell'utente. Ancora associazione dati più appena permesso per l'accesso ai dati mirata — permette agli sviluppatori di includere il file di Office come componente integrato e personalizzabile del app.

Molte applicazioni per ufficio presentano agli utenti con un'interfaccia contenuta unicamente entro i confini dell'attività riquadro o contenuto app UI — e non c'è niente di sbagliato in questo. Ancora, in un senso molto semplice, i dati e la presentazione nell'ambito dell'ufficio file è una "visione" del app. Gli utenti interagiscono con i loro dati all'interno del file di Office. Essi inserire nuovi dati, modificare i dati esistenti ed eliminare dati non necessari all'interno del contenuto del documento. Le applicazioni di Office offrono una visualizzazione dei dati che gli utenti di conoscono e capiscono.

La funzionalità di associazione dati nell'API JavaScript per Office consentono di sfruttare la visualizzazione dei dati che prevede l'applicazione di Office in un app. Si, lo sviluppatore, può sviluppare un 'interfaccia per la vostra applicazione utilizzando ciò che è già fornito a voi in ufficio. In questo modo, è possibile lo stile della vista della vostra applicazione utilizzando le funzionalità out-of-the-box dell'applicazione Office. L'associazione quindi dati forniscono i tendini che collegano la vista dell'app la logica di business "modello" contenuto nel file JavaScript.

Naturalmente, è vero il contrario, pure. È possibile utilizzare i file di Office come origine dati, archiviare il contenuto del modello di dati. È quindi possibile utilizzare l'app per fornire una visualizzazione dei dati. Con la flessibilità di associazioni, è possibile applicare il pattern Model-View-Controller (MVC) per un app e un file di Office come si adatta alle vostre esigenze.

Scenari per le associazioni con senza impostare un limite rigido alla creatività degli sviluppatori, un app può utilizzare associazioni in qualsiasi combinazione di generalizzata in tre modi:

  • L'app reagisce quando l'utente modifica i dati della regione.
  • L'applicazione raccoglie i dati della regione, analizza e presenta all'utente con opzioni per la modellazione o presentare i dati.
  • L'app spinge dati da un'origine dati esterna in regione associata.

Prendiamo, per esempio, un app semplice stock ticker inserito in una cartella di lavoro di Excel, dove una colonna della cartella di lavoro contiene i simboli di stock e l'altro contiene valori attuali stock. Con associazione dati, un'app potrebbe associare alla colonna con i simboli di riserva, raccogliendo i simboli magazzino nella colonna. L'app potrebbe allora Iscriviti a variazioni del prezzo di tali stock tramite un servizio Web e analizzare i risultati inviati dal servizio. Infine, l'applicazione potrebbe associare alla colonna del prezzo del foglio di lavoro e aggiornare i valori in tempo reale.

Lo faremo appena — creare una cartella di lavoro stock ticker — nella prossima sezione come si esamina l'oggetto Binding.

Utilizzando l'oggetto Binding la magia di associazione dati sottostante è contenuta nell'insieme di associazioni e l'oggetto Binding.

  • L'insieme di associazioni rappresenta tutte le associazioni create tra le app e i file di Office per Office. Un app non ha accesso a tutte le associazioni creati da altre applicazioni.
  • L'oggetto Binding rappresenta uno denominato associazione tra una regione nel file di Office e l'app. Esso espone diversi membri per ottenere, la lettura e impostazione dati e reagire ai cambiamenti associati della regione.

Esamineremo più da vicino questi oggetti come costruiamo l'app stock ticker.

Prima di andare ulteriormente, diamo un rapido sguardo ai dati. Figura 1 Mostra come appare la visualizzazione di questa app. Come potete vedere, stiamo usando simboli stock fittizie a scopo dimostrativo.

A Table Named “Stocks” in an Excel Workbook with Formulas and Conditional Formatting Applied
Figura 1 tabella denominata "Stock" in una cartella di lavoro Excel con formule e formattazione condizionale applicata

Inoltre, abbiamo già aggiunto qualche "intelligenza" per questa cartella di lavoro. La regione di dati a cui si desidera associare è stata formattata come una tabella e denominata "Stock". Una formula personalizzata è stato aggiunto ai valori nella colonna di destra per confrontare gli altri valori nella tabella. Abbiamo anche applicato una formattazione condizionale alla tabella per rendere l'icona set vengono visualizzati nella colonna di destra.

Vale la pena notare che abbiamo aggiunto questa cartella di lavoro per la nostra soluzione in Visual Studio 2012 affinché non abbiamo a ricreare il nostro tavolo ogni volta che abbiamo la app di debug. Per aggiungere la cartella di lavoro per la soluzione, tasto destro del mouse il progetto app nella soluzione (il primo progetto elencato in Esplora soluzioni, quando si utilizza il modello predefinito), fare clic su Aggiungi elemento esistente e quindi selezionare la cartella di lavoro. Nelle proprietà del progetto app, impostare quindi l'azione di avvio al tuo file di cartella di lavoro. Durante il debug, è necessario inserire l'app manualmente nella cartella di lavoro (scheda Inserisci | Apps per pulsante Office).

Quando viene inizializzato, la logica aziendale dell'applicazione deve impostare il binding e quindi aggiungere un gestore eventi per l'evento dell'associazione, Office.EventType.BindingDataChanged. Nella Figura 2 viene illustrato il codice. Si noti che noi abbiamo incapsulato il nostro codice all'interno di una funzione anonima autoeseguibile memorizzata nella variabile StockTicker. Il nome della tabella su foglio di calcolo, il nome dell'associazione e l'associazione vengono memorizzati come campi di classe all'interno di StockTicker "classe". StockTicker "classe" espone solo un singolo membro: initializeBinding.

Figura 2 creazione dell'associazione per la cartella di lavoro Excel e aggiungendo un gestore di dati modificati evento nell'associazione

var StockTicker = (function () {
  var tableName = "Sheet1!Stocks",
      bindingName = "Stocks",
      binding;
  // Create the binding to the table on the spreadsheet.
function initializeBinding() {
    Office.context.document.bindings.addFromNamedItemAsync(
      tableName,
      Office.BindingType.Table,
      { id: bindingName },
      function (results) {
        binding = results.value;
        addBindingsHandler(function () { refreshData(); });
    });
  }
  // Event handler to refresh the table when the
  // data in the table changes.
var onBindingDataChanged = function (result) {
    refreshData();
  }
  // Add the handler to the BindingDataChanged event of the binding.
function addBindingsHandler(callback) {
    Office.select("bindings#" + bindingName).addHandlerAsync(
      Office.EventType.BindingDataChanged,
      onBindingDataChanged,
      function () {
        if (callback) { callback(); }
    });
  }
  // Other member methods of this "class" ...
return {
    initializeBinding: initializeBinding
  };
})();

Per stabilire un'associazione tra l'app e la tabella del foglio di lavoro, possiamo utilizzare uno dei diversi metodi della classe documento nell'API JavaScript, tra cui addFromNamedItemAsync, addFromPromptAsync e addFromSelectionAsync. (Si noti che addFromPromptAsync è disponibile solo in Excel ed Excel Web App).

Perché sappiamo che il nome della regione a cui si desidera associare — è la tabella intitolata "Stock" di Sheet1 — abbiamo utilizzato il metodo addFromNamedItemAsync per stabilire l'associazione. Abbiamo passato in nome della tabella utilizzando la notazione di intervallo di Excel (Foglio1!Stock). I risultati di questa chiamata al metodo includono un riferimento all'associazione, che ci permette di memorizzare un riferimento all'associazione nella nostra variabile di associazione (campo di classe).

Nel nostro codice, noi abbiamo passato il valore Office.BindingType.Table per il parametro bindingType del metodo. Questo specifica che si desidera creare un "Tabella" tipo di associazione con i nostri dati, anche se noi potremmo aver specificato anche un tipo testo o matrice di associazione. Associazione per la regione come una tabella ci fornisce diversi vantaggi. Per esempio, se l'utente aggiunge una nuova colonna o una riga alla tabella, l'ambito della regione associata aumenta, troppo. Che funziona l'altro modo, come pure. L'oggetto TableBinding che sottende l'associazione, espone le proprietà per l'aggiunta di colonne, aggiunta di righe e anche l'eliminazione di tutti i dati nella tabella.

(Vedere la sezione intitolata "L'accesso ai File contenuti da un App per ufficio" nel secondo articolo di questa serie per ulteriori informazioni sui tipi di dati testo e matrice nell'API JavaScript per Office).

Il nostro codice aggiunge quindi un gestore per l'evento BindingDataChanged dell'associazione. Quando vengono modificati i dati associati della regione — che è, quando l'utente modifica i dati della regione — vogliamo chiamare una funzione definita localmente refreshData per avviare il processo che aggiorna la tabella. Inoltre, perché la tabella non è stato ancora aggiornata con i dati dall'origine dati, ti vogliamo chiamare refreshData dopo che il gestore eventi è stato aggiunto.

Si noterà che la funzione addBindingsHandler utilizza il metodo Office.select per ottenere l'associazione, anche se noi potessimo hai utilizzato il metodo Bindings.getByIdAsync invece. La differenza principale tra i due metodi è il livello di accesso ai dati restituiti nei risultati. Il metodo Office.select restituisce una promessa di oggetto Binding al codice chiamante. Se il metodo riesce, l'oggetto Binding restituito ha solo un numero limitato di membri disponibili per l'uso. Selezionando l'associazione mediante Office.select, possiamo chiamare membri dall'oggetto Binding immediatamente. In questo modo, non dobbiamo aggiungere una richiamata una funzione che ottiene l'associazione al fine di aggiungere un gestore per l'associazione.

(Si potrebbe pensare che noi potremmo hai appena usato la variabile locale "vincolante" che cattura il riferimento all'associazione — e hai ragione, avremmo potuto avere. Abbiamo scritto questo codice come lo è per scopi dimostrativi.)

Figura 3 Visualizza le funzioni refreshData e getBindingData. La funzione refreshData semplicemente inizia la catena di chiamate asincrone che ottiene i dati della tabella del foglio di lavoro chiamando getBindingData. La funzione getBindingData contiene una chiamata al Metodo Binding.getDataAsync e restituisce i dati come oggetto TableData.

Figura 3 ottenendo i dati dalla tabella di associazione e la chiamata al servizio Web

var StockTicker = (function () {
  // Other members of this "class"...
// Refresh the data displayed in the bound table of the workbook.
// This function begins a chain of asynchronous calls that
  // updates the bound table.
function refreshData() {
    getBindingData();
  }
  // Get the stock symbol data from the bound table and
  // then call the stock quote information service.
function getBindingData() {
    binding.getDataAsync(
      {
        startRow: 0,
        startColumn: 0,
        columnCount: 1
      },
      function (results) {
        var bindingData = results.value,
            stockSymbols = [];
        for (var i = 0; i < bindingData.rows.length; i++) {
          stockSymbols.push(bindingData.rows[i][0]);
        }
        getStockQuotes(stockSymbols);
    });
  }
  return {
    // Exposed members of the "class."
  };
})();

Nella chiamata a getDataAsync mostrato Figura 3, potrebbe aver specificato il tipo di dati da recuperare (o cambiato il tipo di dati) in modo esplicito tramite il passaggio di un oggetto anonimo, {coercionType: Office.CoercionType.Table}, per il parametro options. Perché noi non abbiamo specificato un tipo di dati da recuperare, la chiamata getDataAsync restituisce l'associazione di dati nel tipo di dati originale (un oggetto TableData).

L'oggetto TableData, come abbiamo discusso nel secondo articolo, fornisce i dati che stiamo lavorando con piu ' struttura — vale a dire, un colpo di testa e una proprietà di righe che possiamo utilizzare per selezionare i dati dalla tabella. In questo esempio, abbiamo solo bisogno di ottenere i simboli magazzino dalla prima colonna della tabella. Come ricorderete, la proprietà rows memorizza i dati nella tabella come una matrice di matrici, dove ogni elemento della prima matrice corrisponde a una riga nella tabella.

Quando lavoriamo con un'associazione a un oggetto TableData, possiamo specificare un sottoinsieme di righe e colonne per ottenere dall'associazione, utilizzando i parametri startRow e ColonnaInizio. Entrambi i parametri specificano in base zero punti di partenza per i dati da estrarre dalla tabella, dove l'angolo superiore sinistro della tabella è il punto di origine. (Si noti che è necessario utilizzare i parametri startRow e ColonnaInizio insieme, altrimenti verrà generata un'eccezione). Perché abbiamo solo bisogno della prima colonna di dati della tabella, passiamo anche nel parametro columnCount, impostato su 1.

Una volta che abbiamo la colonna di dati, spingiamo ciascun valore in una matrice unidimensionale. In Figura 3, si vede che noi chiamiamo una funzione getStockQuotes che accetta la matrice dei simboli stock come argomento. In Figura 4, utilizziamo la funzione getStockQuotes per recuperare dati da una servizio Web di quote azionarie. (A scopo dimostrativo, noi abbiamo lasciato fuori il codice per il servizio Web). Dopo che noi abbiamo analizzato i risultati dal servizio Web, chiamiamo il metodo removeHandler definite localmente.

Figura 4 chiamando il servizio Web e rimuovere il gestore eventi BindingDataChanged

var StockTicker = (function () {
  // Other members of this "class"...
// Call a Web service to get new stock quotes.
function getStockQuotes(stockSymbols) {
    var stockValues = [];
    // Make a call to the Web service and parse the results.
// The results are stored in the stockValues variable, which
    // contains an array of arrays that include the stock symbol
    // with the current value.
removeHandler(function () {
      updateTable(stockValues);
    });
  }
  // Disables the BindingDataChanged event handler
  // while the table is being updated.
function removeHandler(callback) {
    binding.removeHandlerAsync(
      Office.EventType.BindingDataChanged,
      { handler: onBindingDataChanged },
      function (results) {
        if (results.status == Office.AsyncResultStatus.Succeeded) {
           if (callback) { callback(); }
        }
    });
  }
  return {
    // Exposed members of the "class."
  };
})();

La funzione removeHandler chiama il metodo binding.removeHandlerAsync, che rimuove un gestore eventi per l'evento BindingDataChanged. Ora, se avevamo lasciato quel gestore all'evento, quindi l'evento avrebbe generato quando abbiamo aggiornato la tabella. Il gestore eventi poi sarebbe stato chiamato nuovamente e vuoi aggiornare la tabella, causando così un ciclo infinito. Dopo che abbiamo aggiornato la tabella con i nuovi dati, aggiungeremo il gestore eventi torna all'evento.

(Naturalmente, abbiamo anche potremmo hai creato diverse associazioni per separare le colonne nella tabella, utilizzando il tipo di coercizione di matrix. Quindi noi potremmo hai collegato eventi solo per le colonne che è possono modificare gli utenti.)

Il metodo removeHandlerAsync accetta un parametro, il gestore, che specifica il nome del gestore per essere rimosso. È consigliabile utilizzare il parametro del gestore per rimuovere i gestori eventi di associazione.

In Figura 5, stiamo andando ad aggiornare la tabella con i nuovi valori di magazzino chiamando la funzione updateTable definite localmente.

Figura 5 ottenendo i dati dalla tabella di associazione e la chiamata al servizio Web

var StockTicker = (function () {
  // Other members of this "class"...
// Update the TableData object referenced by the binding
  // and then update the data in the table on the worksheet.
function updateTable(stockValues) {
    var stockData = new Office.TableData(),
        newValues = [];
    for (var i = 0; i < stockValues.length; i++) {
      var stockSymbol = stockValues[i],
          newValue = [stockSymbol[1]];
      newValues.push(newValue);
    }
    stockData.rows = newValues;
    binding.setDataAsync(
      stockData,
      {
        coercionType: Office.CoercionType.Table,
        startColumn: 3,
        startRow: 0
      },
      function (results) {
        if (results.status == Office.AsyncResultStatus.Succeeded) {
          addBindingsHandler();
        }
    });  
  }
  return {
    // Exposed members of the "class."
  };
})();

La funzione updateTable accetta i dati passati dal servizio Web e quindi lo scrive nuovamente la tabella associata. In questo esempio, il parametro stockValues contiene un altro array di Array, dove ogni elemento della prima matrice è una matrice contenente un simbolo di borsa e il suo prezzo corrente. Per impostare nuovamente questi dati nella tabella associata, si crea un nuovo oggetto TableData e inserire i dati del valore azionario.

Dobbiamo stare attenti a che i dati che abbiamo impostato nella proprietà TableData.rows corrispondano alla forma dei dati che noi stiamo inserendo in associazione. Se abbiamo impostato ciecamente un nuovissimo TableData oggetto nella tabella associata, corriamo il rischio di perdere alcuni dati nella nostra tabella — come le formule, per esempio. In Figura 5, abbiamo aggiunto i dati all'oggetto TableData come un'unica colonna di dati (una matrice di matrici, dove ogni sottomatrice contiene un singolo elemento). Quando inseriamo questo dati nuovamente dentro la tabella associata, abbiamo bisogno di inserire questa colonna aggiornata dei dati nella colonna appropriata.

Qui usiamo ancora le proprietà startRow e ColonnaInizio. La funzione updateTable contiene una chiamata a binding.setDataAsync che spinge indietro il TableData nella tabella del foglio di lavoro, specificando i parametri ColonnaInizio e startRow. Il parametro ColonnaInizio è impostato su 3, significa che l'oggetto inserito TableData inserire i propri dati a partire dalla quarta colonna della tabella. Nel callback per il metodo setDataAsync, che chiamiamo il addBindings­funzione del gestore per riapplicare il gestore eventi per l'evento.

Quando il metodo binding.setDataAsync viene completata con successo, i nuovi dati di tabella sono spinto nella regione associata e visualizzati immediatamente. Dal punto di vista dell'utente, l'esperienza è senza soluzione di continuità. I dati di tipi di utente in una cella della tabella, preme INVIO e quindi aggiorna automaticamente la colonna valore della tabella.

Parti XML personalizzati

Una caratteristica particolarmente degno di nota, supportata da API JavaScript per ufficio è la capacità di creare e manipolare parti XML personalizzati in Word. Al fine di apprezzare il profondo potenziale dell'API JavaScript per ufficio per Web part XML personalizzate, alcuni retroscena è utile. In particolare, è necessario comprendere come il formato di file Office Open XML (OOXML o OpenXML), parti XML personalizzate, controlli contenuto e mapping XML possono essere combinati per creare soluzioni veramente potente — vale a dire, le soluzioni che prevedono la creazione di documenti Word dinamici.

OOXML formati Office 2007 ha introdotto il nuovo formato di file OOXML per i documenti Office, ora il formato di file predefinito per Office 2010 e Office 2013. (Si può dire che i documenti sono in formato OOXML perché le estensioni per quei documenti sono ora le estensioni di quattro lettere, molti dei quali finiscono in "x", per esempio ". docx" per un documento di Word, "xlsx" per un foglio di calcolo Excel o "pptx" per un documento di PowerPoint di Office).

Documenti di Office in formato OOXML sono essenzialmente i file. zip. Ogni file zip contiene un insieme di file XML, denominati "parti", che insieme costituiscono il documento di Office. Se si rinomina un documento di Office, ad esempio un documento di Word con estensione docx in zip e quindi esaminano il file all'interno, si può vedere che il documento è davvero solo un insieme di file XML separati, organizzati in cartelle, all'interno di un pacchetto. zip, come mostrato Figura 6.

File Structure of an Office Open XML Format Document
Figura 6 struttura del File di un documento in formato Office Open XML

Nozioni fondamentali di parti XML personalizzati mentre non ci sono parti XML standard che le applicazioni di Office creano sempre per ogni nuovo documento Office nel formato OOXML (ad esempio, c'è una parte XML incorporata che descrive le proprietà del documento base), la cosa interessante è che è anche possibile aggiungere i tuo parti "XML personalizzato" di un documento di Word, di lavoro di Excel o PowerPoint presentazione. La Web part XML personalizzate vengono aggiunti all'insieme di file XML all'interno del pacchetto zip che costituisce il documento di Office. Una Web part XML personalizzata viene memorizzata all'interno della struttura di file del documento, ma non viene visualizzata all'utente finale. Questo consente di inserire dati business che viaggia con un'istanza specifica di un documento di Office che è nascosto all'interno della struttura del file. Poi si può lavorare con codice XML personalizzato nella tua applicazione, e che è esattamente quello che supporta l'API JavaScript per ufficio.

Controlli contenuto insieme con il formato OOXML e la sua struttura di file che permette l'inserimento di codice XML personalizzato in un documento, Word 2007 Aggiunto controlli contenuto, una caratteristica che si integra pienamente parti XML personalizzate.

Controlli contenuto sono un modo per definire le aree fisse in un documento di Word che contengono determinati tipi di dati, ad esempio testo, RTF, immagini, date e ripetendo anche dati. L'aspetto chiave di controlli contenuto che integra le parti XML personalizzate è associazione dati utilizzando XML mapping.

Mapping XML un controllo contenuto può essere vincolato o "mappato" a un elemento XML in una parte XML che è contenuto nel documento. Ad esempio, un business potrebbe iniettare dati aziendali da un sistema di back-end come una parte XML personalizzata in un documento di Word che ha controlli contenuto mappati alla parte XML personalizzata. Il contenuto di controlli sono associati a specifici nodi XML personalizzato parte così quando l'utente finale apre il documento, i controlli contenuto mapping XML sono automaticamente popolati con i dati da parte XML personalizzato. Oppure, invertendo lo scenario, un business potrebbe utilizzare lo stesso documento di Word con controlli contenuto mappati ma hanno l'utente finale di inserire i dati nei controlli del contenuto. Quando il documento viene salvato, i dati nei controlli contenuti mappati viene salvati nel file XML. Un'applicazione potrebbe poi raschiare i dati da parte XML personalizzata del documento salvato e spingerlo in un sistema di back-end. L'API JavaScript per Office fornisce ricchi di supporto per lo sviluppo di applicazioni esattamente come quelle appena descritte.

Utilizzando l'API JavaScript per ufficio a lavoro con parti Custom XML il modo migliore di camminare attraverso alcune delle parti più significative del XML personalizzato parti API in apps per Office JavaScript Object Model è attraverso un esempio. In questa sezione, usiamo l'esempio di "gestione fatture" (bit.ly/YRdlwt) dalla zona di Esempi delle applicazioni di Office e SharePoint developer portale in modo che si può seguire. L'esempio di gestione fattura è un esempio di un documento dinamico scenario dove un business vuole generare documenti che trarre dati da un sistema di back-end per produrre fatture. In questo caso, i dati sono il nome di un cliente e indirizzo di spedizione e un elenco degli acquisti del cliente associato.

L'esempio include un documento modello utilizzato per creare nuove fatture. Il documento modello ha un layout con il nome del cliente, l'indirizzo e una tabella degli acquisti del cliente. Le sezioni di nome, indirizzo e acquisti cliente del documento sono che controlli ogni contenuto. Ogni controllo contenuto è mappato a un nodo nello schema è stata creata per contenere i dati di fatturazione del cliente, come mostrato Figura 7.

Content Controls on the Document Surface Mapped to a Custom XML Part
Figura 7 controlli contenuto sulla superficie del documento mappato a una Web Part XML personalizzate

L'interfaccia utente per l'applicazione di esempio di gestione fattura è molto semplice, come illustrato nel Figura 8.

The UI for the Invoice Manager Sample App
Figura 8 l'interfaccia utente per l'applicazione di esempio fattura Manager

L'utente finale sceglie un numero di fattura dalla casella a discesa nell'applicazione dell'interfaccia utente e i dati del cliente associati con il numero della fattura sono indicati nel corpo dell'app, come indicato Figura 9.

The Invoice Manager UI Populated with Data from a Custom XML Part
Figura 9 l'interfaccia utente gestione fattura popolato con i dati da una Web Part XML personalizzate

Quando l'utente sceglie il pulsante Popola, l'app spinge i dati visualizzati come una Web part XML personalizzata nel documento. Perché i controlli contenuto vengono mappati ai nodi nella parte XML personalizzato, non appena la parte XML personalizzata viene spinto nel documento i controlli contenuto Visualizza immediatamente i dati per ogni nodo XML a cui sono stai mappate. È possibile sostituire la parte XML personalizzata al volo (come abbiamo fatto qui), ma finché la parte conforme allo schema a cui sono mappati i controlli contenuto, i controlli contenuto mostrerà i dati mappati. Figura 10 indica al gestore fattura forma distinta di imballaggio quando i controlli del contenuto vengono mappati a una Web part XML personalizzata nel documento.

Content Controls Mapped to Nodes in a Custom XML Part Showing Bound Data
Figura 10 controlli contenuto associati a nodi in un Custom XML parte mostrando vincolati dati

L'oggetto CustomXmlParts

CustomXmlParts.addAsync il primo passo nel lavoro con parti custom XML sta imparando come aggiungere a un documento utilizzando l'API JavaScript per l'ufficio. L'unico modo per farlo è utilizzando la customXml­Parts.addAsync Metodo. Come suggerisce il nome, il metodo customXmlParts.addAsync aggiunge un custom XML parte asynchro­nously e ha la seguente firma:

Office.context.document.customXmlParts.addAsync(xml [, options], callback);

Si noti che il primo parametro richiesto per la funzione è una stringa XML. Questo è il file XML per la Web part XML personalizzata. Come abbiamo accennato in precedenza, il manager di fattura utilizza parti XML personalizzate che vengono mappati ai controlli del contenuto sulla superficie del documento, ma prima deve ottenere i dati dei clienti da inserire come XML personalizzati. Nel file InvoiceManager.js, che contiene la logica per l'intera applicazione, l'applicazione simula ricevendo i dati dei clienti da un sistema di back-end utilizzando la funzione definita dall'utente setupMyOrders. Questa funzione crea una matrice di tre oggetti che rappresentano i tre ordini di clienti. Naturalmente, potete, immaginare un numero qualsiasi di modi un business potrebbe memorizzare e ottenere la cronologia degli acquisti di un cliente — ad esempio, un database SQL — ma per semplicità, l'applicazione crea tre ordini cliente "hardwired" proprio all'interno della app.

Una volta che sono stati creati gli oggetti gli ordini, i dati rappresentano devono essere reso in XML che può essere utilizzati nella chiamata a custom­XmlParts.addAsync. Che è ciò che accade nella funzione initializeOrders, che consente di configurare l'applicazione UI e fili i gestori eventi per i controlli sull'interfaccia utente. Il pezzo più importante da notare è il codice jQuery che fili di un gestore eventi per l'evento click del pulsante Populate, come mostrato Figura 11.

Figura 11 cablaggio un gestore eventi per l'evento Click del pulsante Popola

$("#populate").click(function () {
  var selectedOrderID = parseInt($("#orders option:selected").val());
  _document.customXmlParts.getByNamespaceAsync("", function (result) {
    if (result.value.length > 0) {
      for (var i = 0; i < result.value.length; i++) {
        result.value[i].deleteAsync(function () {
        });
      }
    }
  });
  var xml = $.json2xml(findOrder(myOrders, selectedOrderID));
  _document.customXmlParts.addAsync(xml, function (result) { });
});

Essenzialmente, la funzione anonima che agisce come gestore eventi per l'evento click del pulsante Popola converte un oggetto di ordine (che è stato creato con la funzione setupMyOrders) in una stringa XML e quindi chiama il metodo customXmlParts.addAsync e passa la stringa XML che contiene le informazioni di ordine come primo parametro richiesto.

L'altro parametro per customXml­Parts.addAsync è un callback. Naturalmente, questo può essere un riferimento a un metodo definito altrove nel codice, o può essere una funzione anonima. L'esempio di gestione fattura utilizza una funzione anonima inline:

_document.customXmlParts.addAsync(xml,
  function (result) { });

Come avviene per tutte le richiamate in Java­Script API per l'ufficio, un oggetto AsyncResult viene passato come argomento solo per il callback. Per customXmlParts.addAsync e tutte le funzioni di customXmlParts, è possibile utilizzare l'oggetto AsyncResult per:

  • ottenere un riferimento alla parte XML personalizzato appena creato utilizzando l'Async­Result.value proprietà.
  • ottenere il risultato della richiesta tramite la proprietà AsyncResult.status.
  • ottenere informazioni su un errore (se uno si è verificato) utilizzando l'Async­Result.error proprietà.
  • ottenere i vostri dati di stato (se incluso qualsiasi nella chiamata a custom­XmlParts.addAsync) utilizzando la proprietà AsyncResult.asyncContext.

Per tale ultimo elemento, ricordate che l'altro parametro nel metodo customXmlParts.addAsync era un oggetto opzioni facoltative:

Office.context.document.customXmlParts.addAsync(
  xml [, options], callback);

L'oggetto opzioni è fornito come un modo per voi di passare il proprio oggetto definito dall'utente nella chiamata per il callback.

Come si può vedere nell'esempio fattura manager, la funzione anonima nella chiamata a customXmlParts.addAsync non fa nulla, ma in una produzione non è stato aggiunto correttamente ambiente che probabilmente vorreste fare il controllo degli errori per gestire un'istanza con garbo se per qualche motivo la parte XML personalizzata.

CustomXmlParts.getByNamespaceAsync un'altra parte chiave dell'API JavaScript per ufficio per lavorare con le parti XML personalizzate che è dimostrata nell'esempio fattura manager è l'utilizzo del metodo customXmlParts.getByNamespaceAsync, che si può vedere nel codice del gestore eventi click per il pulsante popola. La firma per customXmlParts.getByNamespaceAsync è:

Office.context.document.customXmlParts.getByNamespaceAsync(
  ns [, options], callback);

Il primo parametro richiesto, ns, è una stringa che specifica lo spazio dei nomi delle parti XML personalizzate che si desidera ottenere. Così customXmlParts.getByNamespaceAsync restituisce una matrice di parti custom XML nel documento che hanno lo spazio dei nomi specificato. Poiché le parti XML personalizzate create nell'esempio manager fattura non utilizzano gli spazi dei nomi, la chiamata a customXmlParts.getByNamespaceAsync passa una stringa vuota come argomento per il parametro namespace, come mostrato Figura 12.

Figura 12 utilizzando il metodo CustomXmlParts.getByNamespaceAsync

$("#populate").click(function () {
  var selectedOrderID = parseInt($("#orders option:selected").val());
  _document.customXmlParts.getByNamespaceAsync("", function (result) {
    if (result.value.length > 0) {
      for (var i = 0; i < result.value.length; i++) {
        result.value[i].deleteAsync(function () {
        });
      }
                    }
     });
     var xml = $.json2xml(findOrder(myOrders, selectedOrderID));
     _document.customXmlParts.addAsync(xml, function (result) { });
   });
   var selOrder = $("#orders option:selected");
   popOrder(selOrder.val());

Come tutte le funzioni asincrone nell'API, customXmlParts.getByNamespaceAsync ha richiamata parametri e opzioni facoltative.

CustomXmlParts.getByIdAsync l'ultimo modo programmatico per ottenere una parte XML personalizzata in un documento è il customXmlParts.getByIdAsync. La firma è:

Office.context.document.customXmlParts.getByIdAsync(id [, options], callback);

Questa funzione ottiene una singola parte XML personalizzata utilizzando il GUID della parte. È trovare il GUID per la Web part XML personalizzata nel file itemPropsn.xml all'interno del package del documento. È anche possibile ottenere il GUID utilizzando la proprietà id di customXmlPart. Una cosa fondamentale da notare qui è che la stringa per il GUID deve contenere le parentesi graffe ("{}") intorno il GUID.

L'esempio di gestione fattura non usa il customXml­Parts.getByIdAsync funzione, ma l'esempio di codice riportato di seguito dimostra abbastanza chiaramente:

function showXMLPartBuiltId() {
  Office.context.document.customXmlParts.getByIdAsync(
    "{3BC85265-09D6-4205-B665-8EB239A8B9A1}", function (result) {
    var xmlPart = result.value;
    write(xmlPart.id);
  });
}
// Function that writes to a div with id='message' on the page.
function write(message){
  document.getElementById('message').innerText += message;
}

Oltre il parametro id, come customXmlParts.addAsync e customXmlParts.getByNamespaceAsync, il customXml­Parts.getByIdAsync Metodo ha anche il parametro opzionale, le opzioni e il callback parametro obbligatorio, e sono usate come per le altre funzioni.

L'oggetto CustomXmlPart customXmlPart oggetto rappresenta una singola parte XML personalizzata. Una volta si ottiene un riferimento a un oggetto customXmlPart utilizzando i metodi dell'oggetto customXmlParts, si hanno diverse proprietà disponibili, come mostrato Figura 13.

Figura 13 CustomXmlPart proprietà

Name Descrizione
builtIn Ottiene un valore che indica se l'oggetto customXmlPart è costruito.
id Ottiene il GUID del customXmlPart.
namespaceManager Ottiene l'insieme dei nomi mapping prefisso (customXmlPrefixMappings) utilizzato contro l'attuale customXmlPart.

CustomXmlPart ha anche gli eventi associati con esso, che sono indicate in Figura 14.

Figura 14 CustomXmlPart eventi

Name Descrizione
nodeDeleted Si verifica quando un nodo viene eliminato.
nodeInserted Si verifica quando un nodo viene inserito.
nodeReplaced Si verifica quando un nodo viene sostituito.

Ma per gli scopi di questo articolo, vogliamo concentrarci su alcuni metodi chiave dell'oggetto customXmlPart che verrà spesso utilizzato dagli sviluppatori. Queste righe sono illustrate nella Figura 15.

Figura 15 CustomXmlPart metodi

Name Descrizione
addHandlerAsync In modo asincrono aggiunge un gestore eventi per l'evento di un oggetto customXmlPart.
deleteAsync Elimina in modo asincrono questa parte XML personalizzata dall'insieme.
getNodesAsync Ottiene in modo asincrono qualsiasi customXmlNodes in questa parte XML personalizzata che corrisponda il XPath specificato.
getXmlAsync Ottiene in modo asincrono il XML all'interno di questa parte XML personalizzata.

CustomXMLPart.addHandlerAsync i customXmlPart.add­HandlerAsync metodo è la chiave per cablaggio i gestori di eventi che rispondono ai cambiamenti alla parte XML personalizzata. La firma per il metodo customXmlPart.addHanderAsync è come segue:

customXmlPart.addHandlerAsync(eventType, handler [, options], callback);

Si noti che la prima richiesta di parametro è un'enumerazione di Office.EventType, che specifica quale tipo di evento in apps per il modello a oggetti di Office che si desidera gestire. La successiva richiesta param­eter è il gestore per l'evento. La cosa importante qui è che quando viene richiamato il gestore, l'API JavaScript per ufficio passerà in un parametro di argomenti di evento specifico per il tipo di evento viene gestita (NodeDeletedEventArgs, NodeInsertedEventArgs o NodeReplacedEventArgs). Poi, come in tutte le funzioni asincrone nell'API, avete, facoltativamente, le opzioni e i parametri di callback.

Si consideri lo scenario dove viene utilizzato un documento come un form di immissione dati. L'utente inserisce dati in forma e quindi la forma viene raschiata per i dati. Il modulo contiene un controllo contenuto sezione ripetuta così che ogni volta che l'utente immette un elemento ripetuto, è aggiunto un nuovo nodo alla parte XML personalizzata sottostante. Ogni volta che un nodo è aggiunto, o inserito, viene generato l'evento NodeInserted e può reagire all'evento (e tutti gli eventi customXmlPart) utilizzando customXmlPart.addHandlerAsync.

Figura 16 Mostra come potrebbe rispondere all'evento NodeInserted.

Figura 16 cablaggio un gestore eventi per l'evento CustomXmlPart.NodeInserted

function addNodeInsertedEvent() {
  Office.context.document.customXmlParts.getByIdAsync(
    "{3BC85265-09D6-4205-B665-8EB239A8B9A1}", function (result) {
    var xmlPart = result.value;
    xmlPart.addHandlerAsync(Office.EventType.NodeInserted,
      function (eventArgs) {
        write("A node has been inserted.");
    });
  });
}
// Function that writes to a div with id='message' on the page.
function write(message){
  document.getElementById('message').innerText += message;
}

CustomXMLPart.deleteAsync naturalmente, insieme a sapere come aggiungere una Web part XML personalizzata, è importante sapere come eliminare uno. Il metodo customXmlPart.deleteAsync fornisce tale funzionalità. CustomXmlPart.deleteAsync è una funzione asincrona con la seguente firma:

customXmlPart.deleteAsync([options ,] callback);

Tornando all'esempio di gestione della fattura, è possibile vedere una dimostrazione di customXMLPart.deleteAsync:

$("#populate").click(function () {
  var selectedOrderID = parseInt($("#orders option:selected").val());
  _document.customXmlParts.getByNamespaceAsync("", function (result) {
    if (result.value.length > 0) {
      for (var i = 0; i < result.value.length; i++) {
        result.value[i].deleteAsync(function () {
        });
      }
    }
});

All'interno del gestore eventi click per il pulsante Popola, la logica del programma consente di verificare se esistono eventuali parti XML personalizzate con spazi dei nomi "vuota". Se lo fanno, elimina ogni uno utilizzando il custom­XmlPart.deleteAsync Metodo.

C'è molto di più a lavorare con Web part XML personalizzate, ma quello che noi abbiamo camminato attraverso questo articolo dovrebbe essere sufficiente a dare un senso del supporto per che l'API JavaScript per Office fornisce per la Web part XML personalizzate.

Next Up: Applicazioni di posta

In questo terzo articolo della serie, abbiamo esaminato alcune tecniche avanzate per lavorare con dati in applicazioni per ufficio. Abbiamo mostrato come aggiungere intelligenza supplementare in una tabella di Excel utilizzando associazioni dati. Abbiamo esplorato anche come sfruttare le parti XML personalizzati in un'applicazione per Word facilitare la creazione di documenti automatizzati.

Nell'articolo successivo e finale di questa serie, esamineremo l'API JavaScript per ufficio come si applica per le applicazioni di posta elettronica. Applicazioni di posta elettronica rappresentano un insieme unico di funzionalità all'interno dell'API JavaScript per Office, che consente agli sviluppatori di app e gli amministratori di Exchange costruire potenti strumenti per lavorare con i messaggi di posta elettronica.

Stephen Oliver è uno scrittore programmazione in divisione Office e un Microsoft Certified Professional Developer (SharePoint 2010). Egli scrive la documentazione per sviluppatori per i servizi di Excel e Word Automation Services, insieme alla documentazione sviluppatore servizi di automazione di PowerPoint. Aiutò curato e progettare il sito Mashup di Excel a ExcelMashup.com.

Eric Schmidt è uno scrittore di programmazione nella divisione Office. Ha creato diversi esempi di codice per applicazioni per Office, tra cui il popolare Persist nell'esempio di codice le impostazioni personalizzate. Inoltre, ha scritto articoli e realizzato video su altri prodotti e tecnologie all'interno di programmabilità di Office.

Grazie ai seguenti esperti tecnici per la revisione di questo articolo: Mark Brewster (Microsoft), Shilpa Kothari (Microsoft) e Juan Balmori Labra (Microsoft)
Mark Brewster si è laureato con un B.S. in matematica e scienze informatiche presso la University of Arizona nel 2008 ed ha sviluppato software di Microsoft per quattro anni. Cavalca una bicicletta per divertimento e profitto e ama bere birra e ascoltare album record.

Shilpa Kothari (Gloria) è un software engineer in test presso Microsoft. Ha lavorato su diversi prodotti Microsoft, tra cui Bing Mobile, Visual Studio e ufficio. Lei è appassionata di software QA e l'esperienza utente e può essere raggiunto a shilpak@microsoft.com.

Juan Bobo Labra è un Program Manager che negli ultimi tre anni ha lavorato su Microsoft Office API JavaScript. In precedenza ha lavorato sul rilascio di Office 2010, spedizione duetto e servizi di integrazione applicativa.  Prima di perseguire il suo sogno di muoversi a Redmond, Juan ha lavorato presso Microsoft Messico come l'architetto principale per la pratica di consulenza del settore pubblico.