Estendibilità dell'esperienza utente
Solitamente gli sviluppatori vengono coinvolti quando l'esperienza utente desiderata è difficile o impossibile da realizzare con un approccio low-code. Due degli approcci più comuni adottati da uno sviluppatore per migliorare l'esperienza utente consistono nel creare un componente di codice di Power Apps Component Framework e nell'implementare alcuni script client. I componenti di codice consentono di implementare un oggetto visivo personalizzato che può essere usato da app canvas o basate su modello come qualsiasi altro controllo predefinito. Lo script client non deve essere visivo, ma deve implementare le regole di business in modo programmatico. Lo script client si applica solo alle app basate su modello. Entrambe le tecniche usano modelli prescrittivi e modelli a oggetti che è necessario considerare per l'estendibilità. Nel resto di questo argomento si approfondiranno queste opzioni.
Power Apps Component Framework
I componenti di codice vengono implementati con HTML, CSS e TypeScript. Sebbene non sia necessario usare un framework dell'interfaccia utente specifico, React è uno strumento diffuso.
Per creare un componente di codice, è necessario implementare un'interfaccia che consenta all'app di hosting di interagire con il componente in modo coerente. Per iniziare a sviluppare un componente di codice che implementi l'interfaccia, usare l'interfaccia della riga di comando di Power Platform per inizializzare i file dei componenti da un modello di una colonna o di un set di dati. Questo modello contiene segnaposto per l'implementazione dell'interfaccia richiesta.
L'interfaccia della riga di comando crea un file manifesto che descrive quali file costituiscono il componente come risorse. Inoltre il manifesto identifica eventuali proprietà disponibili per l'uso da parte dell'applicazione che ospita il componente. Nell'esempio seguente è stata definita la proprietà companyName.
Quando i creatori di app usano questo componente, possono impostare staticamente un valore per il nome della società oppure associarlo dinamicamente a una delle colonne di dati disponibili nell'applicazione. Le proprietà consentono all'applicazione e al componente di scambiare comunicazioni sui dati senza che l'app debba comprendere l'implementazione del componente.
Il manifesto consente inoltre di abilitare le funzionalità. Quando una funzionalità viene contrassegnata come obbligatoria nel manifesto, la logica del componente di codice può usare l'API nativa associata alla funzionalità. Ad esempio, l'abilitazione della funzionalità Device.captureAudio consente al controllo del codice di richiamare il microfono del dispositivo per registrare l'audio.
<feature-usage> <uses-feature name="Device.captureAudio" required="true" /> <uses-feature name="Device.captureImage" required="true" /> <uses-feature name="Device.captureVideo" required="true" /> <uses-feature name="Device.getBarcodeValue" required="true" /> <uses-feature name="Device.getCurrentPosition" required="true" /> <uses-feature name="Device.pickFile" required="true" /> <uses-feature name="Utility" required="true" /> <uses-feature name="WebAPI" required="true" /> </feature-usage>
Il runtime dell'app gestisce il ciclo di vita e la comunicazione con il componente di codice ospitato. A questo scopo, la classe del componente di codice implementa l'interfaccia StandardControl.
export class FirstControl implements ComponentFramework.StandardControl<IInputs, IOutputs> {}
Questa interfaccia richiede l'adozione dei seguenti metodi:
init: questo metodo consente di inizializzare l'istanza del componente. I componenti possono avviare chiamate al server remoto e altre azioni di inizializzazione.
updateView: questo metodo viene chiamato quando cambia un valore nel contenitore delle proprietà. Sono inclusi valori di colonna, set di dati, valori globali come altezza e larghezza del contenitore, stato offline e valori dei metadati dei componenti, ad esempio etichetta, visibile e così via.
destroy: questo metodo viene richiamato quando il componente deve essere rimosso dall'albero DOM. Usarlo per la pulizia e per liberare la memoria occupata dal componente.
getOutputs (facoltativo): questo metodo viene chiamato dal framework prima che un componente riceva i nuovi dati. Restituisce un oggetto in base alla nomenclatura definita nel manifesto e prevede che gli oggetti per la proprietà siano contrassegnati come associati.
I componenti di codice richiedono solo l'implementazione del minimo necessario per consentire una comunicazione e un'esperienza coerenti con l'app di hosting.
Script client
Lo script client consente di usare JavaScript nelle app basate su modello Power Apps per implementare le regole di business. Si usano come alternativa quando le regole di business dichiarative non soddisfano i requisiti. Lo script client viene eseguito su un modulo basato su modello in risposta ai seguenti eventi del modulo:
Caricamento del modulo
Cambiamento dei dati in una colonna
Salvataggio del modulo
Inoltre è possibile configurare un pulsante della barra dei comandi in modo che, quando viene premuto, venga richiamato uno script client.
Mentre si scrive la logica in JavaScript, è importante tenere presente che, anche se il modulo è solo HTML, non è possibile manipolarne direttamente il contenuto. Lo script client fornisce un modello a oggetti con chiamate di metodo per interagire con i vari componenti del modulo. In questo modo la logica di business viene isolata da eventuali modifiche nel layout o nell'HTML specifico usato nel rendering del modulo.
Di seguito è riportato un esempio di script client che gestisce sia il caricamento del modulo che il cambiamento della colonna.
// A namespace defined for the sample code
// As a best practice, you should always define
// a unique namespace for your libraries
var Sdk = window.Sdk || {};
(function () {
// Define some global variables
var myUniqueId = "_myUniqueId"; // Define an ID for the notification
var currentUserName = Xrm.Utility.getGlobalContext().userSettings.userName; // get current user name
var message = currentUserName + ": Your JavaScript code in action!";
// Code to run in the form OnLoad event
this.formOnLoad = function (executionContext) {
var formContext = executionContext.getFormContext();
// display the form level notification as an INFO
formContext.ui.setFormNotification(message, "INFO", myUniqueId);
// Wait for 5 seconds before clearing the notification
window.setTimeout(function () { formContext.ui.clearFormNotification(myUniqueId); }, 5000);
}
// Code to run in the attribute OnChange event
this.attributeOnChange = function (executionContext) {
var formContext = executionContext.getFormContext();
// Automatically set some column values if the account name contains "Contoso"
var accountName = formContext.getAttribute("name").getValue();
if (accountName.toLowerCase().search("contoso") != -1) {
formContext.getAttribute("websiteurl").setValue("https://www.contoso.com");
formContext.getAttribute("telephone1").setValue("425-555-0100");
formContext.getAttribute("description").setValue("Website URL, Phone and Description set using custom script.");
}
}
// Code to run in the form OnSave event
this.formOnSave = function () {
// Display an alert dialog
Xrm.Navigation.openAlertDialog({ text: "Record saved." });
}
}).call(Sdk);
È possibile seguire la procedura dettagliata completa di questo esempio per le specifiche su come si collega al modulo.
Con lo script client, uno sviluppatore può rendere un modulo più accessibile a un utente nascondendo e mostrando le colonne appropriate, convalidando i dati ed eseguendo altre attività comuni necessarie per migliorare l'esperienza utente.