Empiece a realizar un seguimiento de su progreso
Inicio de Trailhead
Inicio de Trailhead

Construir una interfaz de usuario para visualizar un registro

Objetivos de aprendizaje

Después de completar esta unidad, podrá:
  • Realizar una solicitud a la API de la interfaz de usuario para obtener datos y metadatos de registros.
  • Comprender por qué y cómo solicitar factores de forma, tipos de formato y modos de acceso.
  • Comprender por qué y cómo solicitar registros secundarios.

Recuperar un registro

Otro de los poderes de la API de la interfaz de usuario es que reúne todo lo que necesita para dibujar la interfaz de usuario. ¿Sabe cuántas solicitudes HTTP hay que hacer para obtener los metadatos de objetos, los metadatos de formato y los datos de campos necesarios para mostrar el registro Contenedores universales? Una.

/ui-api/record-ui/{recordIds}

Veamos el aspecto de la solicitud en el código de Record Viewer. Navegue al archivo /client-src/sagas/recordFetcher.js. Puede mirarlo en GitHub o en su equipo local.

Esta línea construye la URL de destino de la API de la interfaz de usuario.
let recordViewUrl = action.creds.instanceUrl + '/services/data/v48.0/ui-api/record-ui/' 
  + action.recordId + '?formFactor=' + action.context.formFactor + '&layoutTypes=Full&modes=View,Edit';

La solicitud envía un Id. de registro, action.recordId, que es el registro que el usuario selecciona de la Lista de elementos recientes. (El extremo admite múltiples Id. de registro, pero la aplicación Record Viewer solo solicita uno.)

La respuesta incluye la información de formato, que le indica dónde van los campos y en qué secciones de la interfaz de usuario residen. También le indica qué secciones están contraídas, que nosotros denominamos el estado de usuario de formato.

Para especificar qué incluir en la información de formato, la solicitud emplea estos parámetros: formFactor, layoutTypes y modes.

El factor de forma cambia el formato de los campos. Seleccione un factor de forma que coincida con el tipo de hardware en el que se está ejecutando la aplicación. Large es un formato para clientes de escritorio. Medium es un formato para tablets, y Small es un formato para teléfonos. En los factores de forma grandes y medianos, las secciones tienen un formato de dos columnas. En el factor de forma pequeño, las secciones tienen un formato de una columna.

El tipo de formato determina cuántos campos se devuelven. Los tipos de formato posibles son Full y Compact. El formato completo predeterminado incluye todos los campos procedentes del formato de página asignado al usuario actual. El formato compacto incluye todos los campos procedentes del formato de página compacto al usuario actual. Puede modificar ambos tipos de formatos en Configuración. Independientemente del tipo de formato, la respuesta incluye únicamente los campos a los que tiene acceso el usuario.

El modo corresponde a la tarea que está realizando el usuario: Create, View o Edit. La información de formato es diferente dependiendo del modo. Por ejemplo, en modo de creación, el formato no incluye la sección Información del sistema, que incluye campos como Creado por y Última modificación por.

La aplicación Record Viewer solicita los modos de visualización y modificación, de modo que si un usuario hace clic en Modificar, la aplicación ya tiene la información que necesita para representar la interfaz de usuario.

Sugerencia

Sugerencia

Para devolver registros secundarios sin tener que construir consultas que unen dos registros, utilice el parámetro childRelationships. La respuesta se pagina e incluye un nivel de relaciones secundarias. Por ejemplo, esta solicitud devuelve un registro Cuenta y sus registros secundarios Oportunidad.

/ui-api/record-ui/001R0000003IG0vIAG?childRelationships=Account.Opportunities

Enviar solicitudes y actualizar el estado global

La aplicación Record Viewer envía solicitudes de REST a los extremos de la API de la interfaz de usuario y actualiza de forma asíncrona su estado Redux con esa información. Luego el árbol de componentes React… ya se lo puede esperar… reacciona al cambio de estado y actualiza la interfaz de usuario.

Las sagas de Redux gestionan las solicitudes de REST de la aplicación. La solicitud /ui-api/record-ui/{recordIds} se realiza empleando la saga de recordFetcher.js. Este código construye la URL de REST y emite la solicitud empleando el token de acceso de OAuth como Bearer. También establece el encabezado X-Chatter-Entity-Encoding en false para garantizar que los caracteres especiales en el JSON no se devuelven entre caracteres de escape HTML.

Cuando vuelve la respuesta y se analiza correctamente el JSON, la saga se completa enviando una acción RECEIVE_RECORD que incluye la respuesta JSON. En el modelo Redux, las acciones se emiten para expresar una intención de cambiar el estado global. Separando las operaciones que realizar la solicitud externa, modificar el estado y actualizar el componente, mantenemos las cosas emparejadas holgadamente.

En Redux, los reductores interceptan acciones y las utilizan para transformar aspectos del estado global. En este caso, para realizar una actualización de la parte “record” del estado global, el reductor de record.js intercepta la acción RECEIVE_RECORD y procesa su JSON.
/* /reducers/record.js */
case 'RECEIVE_RECORD':
      return {
        record: recordLayout.getLayoutModel(action.recordId, action.record),
        mode: 'View'
      }

La carga JSON se aloja en action.record. El nuevo estado resultante está disponible para componentes a través de state.record. Esta parte del estado procedente del reductor de record.js se ensambla en el estado global en reducers/index.js.

Analizar la respuesta JSON y visualizar el registro

Ahora miremos dentro del auxiliar recordLayout.getLayoutModel() que se utiliza en el reductor de estado de record.js. Incluye los datos, formatos e información de objetos de registros procedentes del JSON /ui-api/record-ui/{recordIds} para crear una estructura de datos. La estructura de datos es el estado que alimenta los componentes React de la aplicación.

En la parte inferior del archivo /client-src/helpers/recordLayout.js, getLayoutModel() ensambla un objeto que aloja:
  • la información de formato
  • un mapa de editValues empleado para realizar un seguimiento de los cambios realizados en valores de campos en la interfaz de usuario
  • el único objectInfo correspondiente al registro disponible
  • el Id. de registro

La función recordLayout.getLayoutModel() procesa la información de formato a medida que pasa por los formatos. Para cada sección en cada formato de la respuesta, llamamos a getLayoutSectionModel(). Este método recupera la información del encabezado de secciones procedente del JSON de sección. Luego pasa por cada fila de la sección, y dentro de cada fila, pasa por cada elemento del formato.

Para cada elemento de formato, getLayoutItemModel() ensambla un objeto que aloja:
  • una lista anidada de valores (pueden ser valores múltiples en un elemento para cosas como direcciones)
  • información de vínculos (vínculos a otros registros)
  • información de vínculos personalizados (vínculos a direcciones URL externas)

Cada uno de los valores alberga información sobre qué mostrar como texto, la etiqueta, los metadatos de campos, la capacidad de modificación y la URL de la lista de selección de la API de la interfaz de usuario correspondiente, cuando sea apropiado.

Existen algunos casos especiales en este método porque hacemos cosas especiales con los valores de listas de selección, las referencias, las fechas y los elementos que no son campos. En el caso típico, para un elemento de formato respaldado por un campo que no sea de fecha, extraemos las propiedades displayValue y value de la entrada correspondiente en el JSON de datos del registro.
} else if (record.fields[compValue]) {
        var displayValue = record.fields[compValue].displayValue;
        let rawValue = record.fields[compValue].value;
        if (displayValue == null && rawValue != null) {
          displayValue = rawValue.toString();
        }
        values.push(
          {displayValue: displayValue,
           value: rawValue,
           label:component.label,
           field:compValue,
           fieldInfo,
           picklistUrl,
           editableForNew:item.editableForNew,
           editableForUpdate:item.editableForUpdate,
           isNull:displayValue == null})

Representar componentes de formato

Como aprendimos, el objeto devuelto desde recordLayout.getLayoutModel() se guarda en el estado global como state.record.record. Este estado se utiliza para representar componentes correspondientes en la interfaz de usuario. El contenedor de nivel superior RecordViewerWrapper.js comprueba si state.record.record está disponible y lo pasa a un componente RecordViewer.js anidado en la propiedad record. Anidados dentro del componente RecordViewer.js, RecordSection.js y RecordRow.js representan sus secciones y filas.

Mire RecordRow.jsgetViewItemCells() en particular. Cuando representamos cada celda de la fila, la alegre ruta crea un <div> para cada componente del elemento. Le damos a <div> una clave porque React lo requiere. Utilizamos displayValue para representar el texto que ve en la pantalla.
{ item.values.map((component, i) => {
             if (component.displayValue && component.displayValue.length > 0) {
               if (component.fieldInfo.htmlFormatted) {
                 return (
                   <div key={'component' + itemLabel + ',' + i} dangerouslySetInnerHTML={{__html: component.displayValue}}></div>
                 )
               } else {
                 return (
                   <div key={'component' + itemLabel + ',' + i}>{component.displayValue}</div>
                 )
               }
             } else {
               return null
             }
           }
          )}

El resultado es que nuestra aplicación la alimenta dinámicamente la información de formato y objetos devuelta por la API de la interfaz de usuario. En vez de codificar campos y posiciones de campos en el formato, utilice la API de la interfaz de usuario para construir una interfaz de usuario que puede reorganizarse a sí misma en el momento que el administrador actualiza formatos y objetos en Salesforce.