Progetti di esempio e casi di utilizzo > Caso di utilizzo: 3D-Guided Service Instructions > 3D-Guided Service Instructions 302 - Aggiungere un servizio ThingWorx semplice a Vuforia Studio > Chiamare getPriceAvailability e utilizzare il listener di eventi serviceInvokeComplete
  
Chiamare getPriceAvailability e utilizzare il listener di eventi serviceInvokeComplete
Una volta aggiunto il servizio getPriceAvailability a Vuforia Studio è necessario richiamarlo nell'esperienza per rendere i dati accessibili per la manipolazione. A tale scopo, è necessario aggiornare il codice di 3D-Guided Service Instructions 301. Inoltre, è necessario aggiungere un nuovo listener di eventi al codice per rendere i dati di questo servizio accessibili dall'esperienza.
* 
Il codice completo di questa sezione è disponibile in Appendix 1 in GitHub.
1. Aprire Home.js.
2. Nel listener di eventi userpick apportare le modifiche riportate di seguito.
a. Eliminare la variabile priceString. I dati sono ora accessibili da shoppingThing in Vuforia Studio anziché dagli attributi nel modello.
b. Creare un oggetto denominato meta e impostarlo sull'ambito dell'applicazione in modo che diverse funzioni dello script possano accedervi. Modificare le variabili partName, instructionName e partNumber in modo che siano proprietà dell'oggetto meta.
//
// create an object with the properties below that are based on attribute names from Creo Illustrate for this model. Use metadata.get to obtain the data from the JSON properties for this occurrence.
$scope.meta = {
partName : metadata.get(pathId, 'Display Name'),
instructionName : metadata.get(pathId, 'illustration'),
partNumber : metadata.get(pathId, 'partNumber'),
} // $scope.meta end
c. Eliminare la variabile price e il parametro dell'applicazione priceInfo poiché dipendevano direttamente dalla variabile priceString.
d. Modificare la definizione dei parametri dell'applicazione itemName e itemNumber in modo che siano coerenti con la nuova sintassi per la chiamata di partName e partNumber dall'oggetto meta. Creare quindi una nuova variabile denominata target (con ambito dell'applicazione) e impostarla sulla variabile targetName dall'evento userpick.
//
// set itemName app parameter to be equal to the partName variable, same relationship with itemNumber and partNumber and priceInfo and price.
// Set the itemCount to 1 for the purpose of this section, since it is not hooked up to an actual inventory.
$scope.app.params.itemName = $scope.meta.partName;
$scope.app.params.itemNumber = $scope.meta.partNumber;
$scope.app.params.itemCount = 1;

$scope.target = targetName;
e. Aggiungere il codice riportato di seguito per attivare il servizio getPriceAvailability all'interno di shoppingThing. Questo codice ha il formato twx.app.fn.triggerDataService ('<entità TWX>', '<servizio TWX>', '<parametro>'). La funzione triggerDataService chiama un servizio fornito da ThingWorxVuforia Studio, in cui vengono richiamati l'entità e il servizio ThingWorx, insieme ai parametri di input che il servizio richiede. Nel nostro caso, l'oggetto che viene chiamato è shoppingThing che contiene tutte le informazioni sulla parte, il servizio chiamato (getPriceAvailability) e il parametro (pid), che è un parametro per il numero di parte della parte selezionata. L'output di questo servizio viene chiamato utilizzando un callback asincrono, che chiama il listener di eventi serviceInvokeComplete. Il listener di eventi serviceInvokeComplete verrà creato più avanti in questa sezione.
//
// call the getPriceAvailability ThingWorx service based on partNumber
twx.app.fn.triggerDataService('shoppingThing', 'getPriceAvailability', {pid: $scope.meta.partNumber})
f. L'istruzione if per i popup di seguito viene trasferita dal listener di eventi userpick al listener di eventi serviceInvokeComplete. Copiare le parentesi di chiusura dell'API PTC Metadata, l'istruzione catch e le parentesi di chiusura di userpick e incollarle sotto il trigger del servizio. Eliminare il codice appena copiato da sotto la funzione di disassemblaggio del popup, altrimenti saranno presenti parentesi aggiuntive.
}) //end brackets for PTC API and .then
//
//catch statement if the promise of having a part with metadata is not met
.catch( (err) => { console.log('metadata extraction failed with reason : ' +err) })
}) //end brackets for userpick function. Will continue to move throughout code
3. Con il listener di eventi userpick aggiornato, è il momento di creare il listener di eventi serviceInvokeComplete. Questo listener di eventi viene attivato solo dopo il completamento del servizio getPriceAvailability.
a. Aggiungere il codice riportato di seguito per il listener di eventi sopra l'istruzione if per il popup. Selezionare il codice dall'inizio dell'istruzione if fino alla fine della funzione disassemble e annullare il rientro per allinearlo correttamente.
* 
Accanto a questa riga è presente una X in un cerchio rosso perché la parentesi di chiusura non è ancora stata creata. Questo è un comportamento previsto.
$scope.$on('getPriceAvailability.serviceInvokeComplete', function(evt) {
b. Ora che i dati vengono aggiunti dinamicamente da ThingWorx, il processo di chiamata del popup viene modificato. Sotto al listener di eventi serviceInvokeComplete, creare una variabile denominata rowData che utilizza la riga corrente dell'infotable creata con il servizio getPriceAvailability.
//
// variable holding all data for the current row in the infotable
var rowData = twx.app.mdl['shoppingThing'].svc['getPriceAvailability'].data.current
c. Successivamente, aggiungere uno script per determinare il prezzo dell'oggetto selezionato. La variabile price utilizza le informazioni di ThingWorx e viene impostata su una stringa con il prezzo della parte nella riga selezionata preceduto dal simbolo $ oppure sulla dicitura ‘UNAVAILABLE’ se la parte non è disponibile. Le informazioni utilizzate dalla variabile price vengono create tramite un operatore condizionale che convalida che la parte è disponibile prima di controllarne il prezzo. Questa operazione può essere eseguita anche utilizzando un'istruzione if con le stesse condizioni. Una logica simile viene utilizzata per creare il parametro dell'applicazione priceInfo utilizzato per l'aggiunta di prezzi nel carrello.
//
// price is going to be the variable that is referenced in the popup, while the app parameter priceInfo will be used for adding the total in the cart
var price = rowData.avail === true ? '$' + rowData.price
: 'UNAVAILABLE';
$scope.app.params.priceInfo = rowData.avail === true ? parseFloat(rowData.price)
: undefined ;
d. Creare una variabile denominata meta e utilizzata per portare l'oggetto $scope.meta nel listener di eventi come oggetto locale per facilitate l'accesso ai relativi valori.
//
// create a variable to bring the $scope.meta object into this event listener as a local object
let meta = $scope.meta
e. Poiché al popup vengono aggiunte ulteriori informazioni per determinare se una parte è disponibile o meno in base alle informazioni di shoppingThing, il modello per il popup viene impostato utilizzando una funzione che verrà creata in un secondo momento nell'attività. Quindi, per ora, eliminare le condizioni e le parentesi di chiusura dell'istruzione if creata in precedenza e annullare il rientro del codice per la chiamata del popup.
f. Eliminare il codice del popup che in precedenza corrispondeva al caso else nell'istruzione if. Eliminare inoltre il valore della proprietà template, che verrà sostituito nel passo successivo. Accanto a queste righe di codice sono presenti indicatori di errore che vengono risolti una volta completato il valore del modello.
g. La proprietà template deve avere un valore che chiama la funzione setTemplate (che verrà creata successivamente) con gli input dell'oggetto meta e la variabile price per la parte selezionata. Il codice per chiamare il popup deve ora coincidere con il codice specificato di seguito.
//
// adds an ionic popup when a part is clicked
$scope.popup = $ionicPopup.show({
//
//call the function for setting the template
template: $scope.setTemplate(meta, price),
//
// set the scope for the popup
scope: $scope
}); //end of ionic popup
h. Per la funzione disassemble devono essere aggiornate le proprietà model e instruction in modelObject per impostare la sequenza di animazione del modello. È qui che si accede alla variabile $scope.target creata in precedenza e instructionName si aggiorna con la nuova posizione all'interno dell'oggetto meta.
//
// function to be bound to the Disassemble button in the popup
$scope.disassemble = function () {
//
// set an object that targets the model and its instruction property
var modelObject = { model: $scope.targetName,
instruction: 'l-Creo 3D - ' + meta.instructionName + '.pvi' };
//
// set the sequence for the quadcopter to be the name of the associated instruction
$scope.view.wdg.quadcopter.sequence = modelObject.instruction
} //disassemble function end
i. Aggiungere una parentesi graffa e una tonda di chiusura per completare la chiamata al servizio getPriceAvailability.
}) // getPriceAvailability end
4. Per semplificare il processo di utilizzo dei popup Ionic nell'esperienza, è necessario aggiungere un altro listener di eventi userpick. Questo listener di eventi viene utilizzato per chiudere un popup che non è stato chiuso prima di fare clic su un'altra parte. Quando è attivato, il listener di eventi chiude il popup della prima parte su cui si è fatto clic e ne rimuove lo shader prima di aprire un nuovo popup e shader nella parte successiva selezionata.
//
// userpick event listener that will take place when you click on another part without choosing an option in the popup
$scope.$on('userpick', function (event, targetName, targetType, eventData) {

//
// close the popup and remove the shader from the part even when you didn't chose an option from the popup
$scope.popup.close()

$scope.hiliteOff()

}) // closing userpick end
5. Il passo finale per l'aggiornamento dell'esperienza consiste nel creare la funzione setTemplate citata in precedenza. Questa funzione viene utilizzata per impostare la variabile template utilizzata nel popup per determinare le informazioni disponibili per la parte. Include la logica per determinare se esiste una sequenza di disassemblaggio associata a una parte e se è disponibile in shoppingThing.
a. Sotto la funzione clearCart, creare una funzione denominata setTemplate con gli input di meta e price.
//
// function for setting the template for the Ionic popup
$scope.setTemplate = function (meta, price) {

} // setTemplate end
b. Per prima cosa si aggiunge la logica alla funzione per determinare se esiste una sequenza di disassemblaggio associata alla parte selezionata. La variabile instr utilizza un operatore condizionale per verificare se la proprietà instructionName di meta è stata completata o meno e sostituisce l'istruzione if precedentemente. Se è associata una sequenza, viene creato un pulsante che può essere selezionato per attivare la funzione disassemble, disattivare lo shader e chiudere il popup. Se non è associata una sequenza, instr diventa una stringa vuota.
//
// if there is a disassembly sequence associated with the part, create a Disassemble button in the popup, if not, no button will appear
var instr = meta.instructionName.length > 0 ? '<div class="btndisassemble" ng-click="hiliteOff();popup.close();disassemble();">Disassemble</div>'
: '';
c. Inoltre, è necessario aggiungere la logica per determinare se una parte è disponibile o meno. Creare la variabile addTo come risultato di un operatore condizionale che determina se a una parte è associato o meno un prezzo, in base alle informazioni presenti in shoppingThing. In caso affermativo, il prezzo viene visualizzato nel popup insieme a un pulsante selezionabile Add to Cart che attiva la funzione addToCart. Altrimenti, al popup viene aggiunto solo il prezzo.
//
// if price != unavailable, define an add to cart button and have the price displayed in the popup, if it is unavailable, just display price
var addTo = price != 'UNAVAILABLE' ? price + '&nbsp; </div><div class="btnadd" ng-click="hiliteOff();popup.close();addToCart();">Add to Cart</div>'
: price ;
d. Dopo aver determinato i pulsanti disponibili per il popup viene creata la variabile template esattamente come quella creata per i popup precedenti. Il popup visualizza la quantità, il numero della parte, il nome della parte e il prezzo della parte selezionata, insieme ai pulsanti che si applicano alla parte. Il pulsante Continue viene aggiunto di nuovo per chiudere il popup. Viene aggiunta un'istruzione RETURN per la variabile template in modo che venga generata dalla funzione quando viene eseguita. In questo modo viene completata la funzione setTemplate.
//
// build the template for the popup
var template = '<div>' + $scope.app.params.itemCount + 'x  ' + meta.partNumber +
'&nbsp;</br>' + meta.partName +
'&nbsp;</br>' + addTo + instr +
'<div class="btncontinue" ng-click="hiliteOff();popup.close();">Continue</div>' ;

//
// return the template variable when this function is called
return template
6. Fare clic su Anteprima.
a. Fare clic sulla base del quadrirotore per visualizzare il popup mostrato quando una parte è disponibile ma non è associata a una sequenza di disassemblaggio. Fare clic su Continue per chiudere il popup.
* 
Se non si fa clic sul pulsante Continue prima di fare clic su un'altra parte, il primo popup non si chiude e pertanto i popup vengono sovrapposti l'uno all'altro.
b. Selezionare uno dei rotori per visualizzare il popup mostrato quando una parte è disponibile ed è associata a una sequenza di disassemblaggio.
c. Selezionare la parte superiore del quadrirotore per visualizzare il popup mostrato quando una parte non è disponibile e non è associata a una sequenza di disassemblaggio.
Selezionare uno dei motori per visualizzare il popup mostrato quando una parte non è disponibile ed è associata a una sequenza di disassemblaggio.
7. Questa sezione è stata completata. Tutti gli altri codici in questa sezione sono identici a quelli presenti in 3D-Guided Service Instructions 301. Facendo clic su una parte, dovrebbe venire visualizzato un popup con una delle quattro opzioni elencate sopra. Se applicabile, dovrebbe anche essere possibile aggiungere la parte al carrello. Dovrebbe anche essere possibile cercare le parti utilizzando il widget userInput.
Nell'ultima sezione di questo caso di utilizzo si creerà il carrello persistente utilizzando ThingWorx.