Evento OnSave de formulario (referencia de API de cliente) en aplicaciones basadas en modelos

El evento OnSave se produce cuando:

  • El usuario selecciona el icono Guardar o Actualizar en la barra de comandos, incluso cuando no hay datos modificados para guardar.
  • El código ejecuta el método formContext.data.entity.save, incluso si no hay datos modificados para guardar.
  • El usuario navega fuera del formulario y hay datos sin guardar en el formulario.
  • La opción Autoguardado está habilitada, 30 segundos después de que los datos han cambiado y hay datos sin guardar en el formulario.
  • El código ejecuta el método formContext.data.save y hay datos sin guardar en el formulario.
  • El código ejecuta el método formContext.data.refresh que pasa un valor true al primer parámetro y hay datos sin guardar en el formulario.

Nota

El evento OnSave para citas, citas periódicas o registros de actividad de servicio cancelará la operación de guardar y utilizará el mensaje Book para que persista el cambio, en vez de Create o Update. Por este motivo, los controladores de eventos OnSave y PostSave de estas tablas no funcionarán.

Para determinar en qué botón se ha hecho clic para realizar la acción de guardar, use el método getSaveMode.

Puede cancelar la acción de guardar mediante el método preventDefault en el objeto de argumentos del evento. Se puede acceder al método preventDefault mediante el método getEventArgs que forma parte del contexto de ejecución. El contexto de ejecución se transfiere automáticamente al controlador de eventos del formulario.

Compatibilidad con el controlador de eventos asincrónico

El evento OnSave tiene la capacidad de esperar a que se resuelvan las promesas devueltas por los controladores de eventos antes de guardar, lo que permite al evento OnSave ser asincrónico ("async").

El evento OnSave se vuelve asíncrono cuando el controlador de eventos OnSave devuelve una promesa. El guardado del registro ocurre cuando se resuelve cada promesa devuelta por un controlador. Para las promesas que se devuelven, hay un límite de 10 segundos para cada promesa, después de eso, la plataforma considera que las promesas están vencidas. Este tiempo de espera se aplica según la promesa. Por ejemplo, si tenemos cinco promesas devueltas, el tiempo total de espera es de 50 segundos.

Si la promesa se rechaza o se agota el tiempo de espera, la operación de guardado continúa comportándose de manera similar a los errores de secuencia de comandos actuales. Use el método preventDefault dentro del objeto de argumentos de evento en ese controlador en particular si desea evitar que suceda el evento de guardado si hay un error de secuencia de comandos / promesa rechazada o tiempo de espera del controlador.

También puede cancelar la operación de guardado independientemente del error en el controlador o de no usar el método preventDefault dentro del objeto de argumentos de evento. Si se llama a este método, el evento Async OnSave espera a que se resuelvan todas las promesas, pero no se guardará. Al llamar a este método la lógica dentro de .then() & .catch() se ejecutará.

El evento OnSave espera a que se devuelva una promesa por controlador. Si se requieren varias promesas, se recomienda encapsular todas las promesas en el método Promise.all() y devolver la única promesa resultante. Para varios controladores que devuelven una promesa, le recomendamos que cree un controlador que llame a todos los eventos y devuelva una única promesa que encapsule todas las promesas requeridas. Esta práctica es para minimizar los tiempos de espera causados por el tiempo de espera.

Escenario de ejemplo sobre cuándo usar controladores OnSave asíncronos

Considere la posibilidad de crear una tarea de servicio de orden de trabajo, debe validar que el activo del cliente seleccionado tenga la misma cuenta que aparece en la orden de trabajo. La obtención de la cuenta en la orden de trabajo y el activo del cliente son procesos asincrónicos y deben completarse antes de que se pueda realizar la validación.

En este escenario, dado que hay varios procesos asíncronos y ambas llamadas devuelven una única promesa al encapsular ambas en el método Promise.all().

Nota

El método preventDefault solo se puede utilizar de forma sincrónica.

Por ejemplo:

 function myHandler(context) {
    return new Promise((resolve) => {
       setTimeout( () => {
          context.getEventArgs().preventDefault();
       }, 1000);
   });
 }

Habilitar Async OnSave usando la configuración de la aplicación

Para usar controladores onSave asíncronos, debe habilitarlos a través de una configuración de aplicación.

  1. Vaya a https://make.powerapps.com.

  2. Asegúrese de seleccionar el entorno correcto.

  3. Seleccione Aplicaciones en el panel de navegación izquierdo.

  4. Seleccione la aplicación y, a continuación, seleccione ... (puntos suspensivos). Seleccione Editar.

  5. Seleccione Configuración en la barra de comandos.

  6. Cuando se abra el cuadro de diálogo, seleccione Características.

  7. Active Controlador onSave asincrónico.

  8. Seleccione Guardar.

    Configuración de la aplicación Async OnSave

Tiempos de espera de OnSave asincrónico

Cuando usa un controlador asíncrono OnSave, el formulario espera a que se devuelva la promesa desde el controlador. Para asegurarse de que el formulario guardado se complete a tiempo, el controlador lanza una excepción de tiempo de espera después de 10 segundos para informarle que debe ajustar el controlador de OnSave asincrónico para un mejor rendimiento.

Hay escenarios en los que es necesario pausar el controlador OnSave durante más de 10 segundos. Un ejemplo es abrir un diálogo y esperar la entrada del usuario antes de guardar. Para asegurarse de que la operación asíncrona espere a que se resuelva la promesa, use el método disableAsyncTimeout.

Nota

Debe llamar a disableAsyncTimeout antes de cualquier declaración de espera o llamada asíncrona.

Por ejemplo:

async function myHandler(context) {  
     context.getEventArgs().disableAsyncTimeout();
     // The 10000ms time out will not be disabled if the above line does not come before all async awaits
     await Xrm.Navigation.openConfirmDialog({ text: "Are you sure you want to save?" });
 }

Cuando se llama a disableAsyncTimeout, no se aplica el tiempo de espera para ese controlador. Continúa esperando que se cumpla la promesa de ese manejador.

Este patrón debe usarse con precaución ya que podría afectar el rendimiento del guardado del formulario.

Artículo relacionado

Evento OnSave de cuadrícula

Nota

¿Puede indicarnos sus preferencias de idioma de documentación? Realice una breve encuesta. (tenga en cuenta que esta encuesta está en inglés)

La encuesta durará unos siete minutos. No se recopilan datos personales (declaración de privacidad).