Extensibilidad de la experiencia del usuario

Completado

Los desarrolladores suelen estar involucrados cuando la experiencia de usuario deseada es difícil o imposible de lograr mediante la adopción de un enfoque de poco código. Dos de los enfoques más comunes para que un desarrollador mejore la experiencia del usuario es crear un componente de código Power Apps Component Framework o implementar scripting del cliente. Los componentes de código le permiten implementar un objeto visual personalizado que pueden utilizar las aplicaciones de lienzo o basadas en modelo como cualquiera de los controles listos para usar. El scripting del cliente no está destinado a ser un objeto visual, sino a implementar reglas de negocio de manera programática. El scripting del cliente solo se aplica a aplicaciones basadas en modelo. Ambas técnicas siguen patrones prescriptivos y modelos de objetos que debe conocer cuando utilice alguna de estas opciones para la extensibilidad. En el resto de este tema, veremos con más detalle ambas opciones.

Power Apps Component Framework

Los componentes de código se implementan con HTML, CSS y TypeScript. Si bien no es necesario que utilice ningún marco de interfaz de usuario en concreto, React es una opción popular.

Para crear un componente de código, debe implementar una interfaz que proporcione una forma coherente para que la aplicación de hospedaje interactúe con el componente. Para comenzar a desarrollar un componente de código que implemente dicha interfaz, utilice la herramienta de interfaz de línea de comandos (CLI) de Power Platform para inicializar los archivos de componentes a partir de una plantilla de una columna o un conjunto de datos. Esta plantilla incluye marcadores de posición para la implementación de la interfaz requerida.

La herramienta CLI crea un archivo de manifiesto que describe los archivos que conforman su componente como recursos. El manifiesto también identifica las propiedades que están disponibles para que las utilice la aplicación que hospeda el componente. En el siguiente ejemplo se ha definido una propiedad companyName.

Cuando los creadores de aplicaciones utilicen este componente, tendrán la opción de establecer de forma estática un valor para el nombre de la empresa o enlazarlo dinámicamente a una de las columnas de datos disponibles en la aplicación. Las propiedades permiten que la aplicación y el componente se comuniquen sobre los datos sin que la aplicación tenga que comprender la implementación del componente.

El manifiesto también le permite habilitar diversas características. Cuando se habilita una característica marcándola como requerida en el manifiesto, la lógica del componente de código puede usar la API nativa asociada a la característica. Por ejemplo, habilitar la características Device.captureAudio permite el control de código para invocar el micrófono del dispositivo y grabar 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>

El tiempo de ejecución de la aplicación gestiona el ciclo de vida y la comunicación con el componente de código hospedado. Esto se logra mediante la implementación de la interfaz StandardControl por parte de la clase del componente de código.

export class FirstControl implements ComponentFramework.StandardControl<IInputs, IOutputs> {}

Esta interfaz requiere que implemente los siguientes métodos:

  • init: se utiliza para inicializar la instancia del componente. Los componentes pueden iniciar llamadas a servidores remotos y otras acciones de inicialización.

  • updateView: se llamará a este método cuando haya cambiado cualquier valor en el contenedor de propiedades. Esto incluye valores de columna, conjuntos de datos, valores globales como la altura y el ancho del contenedor, estado sin conexión, valores de metadatos de componentes como etiqueta, visible, etc.

  • destroy: este método se invoca cuando el componente debe eliminarse del árbol DOM. Utilícelo para la limpieza y para liberar la memoria que el componente esté usando.

  • getOutputs (opcional): el marco lo llama antes de que un componente reciba los nuevos datos. Devuelve un objeto basado en la nomenclatura definida en el manifiesto, y espera objetos para la propiedad marcada como enlazada.

Los componentes del código solo requieren que implemente el mínimo necesario para permitir una comunicación y una experiencia coherentes con la aplicación de hospedaje.

Scripting del cliente

El scripting del cliente le permite utilizar JavaScript en aplicaciones basadas en modelos de Power Apps para implementar reglas de negocio. El scripting del cliente debe utilizarse como alternativa cuando las reglas de negocio declarativas no cumplen los requisitos. El scripting del cliente se ejecuta en un formulario basado en modelo en respuesta a los siguientes eventos de formulario:

  • Carga del formulario

  • Los datos de una columna cambian

  • El formulario se guarda

Además, se puede configurar un botón de la barra de comandos para invocar un script de cliente cuando se presiona.

Mientras escribe su lógica en JavaScript, es importante tener en cuenta que, aunque el formulario es solo HTML, no puede manipular directamente el contenido del formulario. El scripting del cliente proporciona un modelo de objeto con llamadas a métodos para interactuar con los distintos componentes del formulario. Esto garantiza que su lógica de negocios esté aislada de cualquier cambio en el diseño o HTML específico que se utilice en la representación del formulario.

A continuación se expone un ejemplo de scripting del cliente en el que se muestra tanto la carga del formulario como el cambio de columna.

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

Puedes seguir el tutorial completo de este ejemplo para obtener detalles sobre cómo se conecta al formulario.

Si un desarrollador utiliza el scripting del cliente puede hacer que un formulario sea más accesible para un usuario al ocultar y mostrar las columnas adecuadas, validar los datos, y otras tareas comunes necesarias para mejorar la experiencia del usuario.