Actualizar registros de datos en una aplicación DOM virtual de Oracle JET

Introducción

En este tutorial se muestra cómo utilizar la aplicación DOM virtual de Oracle JavaScript Extension Toolkit (Oracle JET) para actualizar un registro de datos existente y enviarlo a un servicio REST.

Objetivos

En este tutorial, aprenderá a actualizar un registro de datos existente y enviarlo a un servicio REST.

Requisitos

Tarea 1: Creación de componentes para gestionar información de formulario

Cree un nuevo componente que muestre un cuadro de diálogo para llamar a la funcionalidad para actualizar un registro.

  1. Navegue al directorio JET-Virtual-DOM-app/src/components/ActivityItem, cree un nuevo archivo EditItemDialog.tsx y ábralo en un editor.

  2. Agregue las entradas de marcador de posición que definen un nombre de función (EditItemDialog) para el nuevo componente.

    import { h } from "preact";
    
    type Props = {
      message?: string;
    };
    
    const EditItemDialog = (props: Props) => {
      return (
        <div class="oj-web-applayout-max-width oj-web-applayout-content">
          <p>content</p>
        </div>
      );
    };
    
    export default EditItemDialog;
    

Tarea 2: Manejo de la apertura del cuadro de diálogo

Declare el tipo y la función en el componente ItemActionsContainer para llamar al componente EditItemDialog que contiene la funcionalidad para actualizar un registro.

  1. Navegue al directorio JET-Virtual-DOM-app/src/components/ActivityItem y abra el archivo ItemActionsContainer.tsx.

  2. En la parte superior del archivo, importe los enlaces de preferencia useState y useEffect y, a continuación, defina las propiedades adicionales en un alias de tipo Props que necesita para utilizar el componente EditItemDialog.

    import { h } from "preact";
    import "ojs/ojbutton";
    import { useState, useEffect } from "preact/hooks";
    
    type Props = {
       create: () => void;
       edit: () => void;
       itemSelected: any;
    };
    
  3. Antes de la sentencia return, utilice los enlaces Preact que ha importado para determinar si se ha seleccionado un elemento de actividad.

    	const ItemActionsContainer = (props: Props) => {
    	  const [hideActions, setHideActions] = useState<boolean>(true);
    
    	  	  if (props.itemSelected?.id) {
    		console.log("Selected: " + JSON.stringify(props.itemSelected));
    	  }
    
    	  useEffect(() => {
    		if (props.itemSelected?.id) {
    		  setHideActions(false);
    		} else {
    		  setHideActions(true);
    		}
    	  }, [props.itemSelected]);
    
    	  return (
    
  4. En la sentencia return, agregue un nuevo elemento oj-button con un atributo onojAction que haga referencia a la propiedad edit.

    const ItemActionsContainer = (props: Props) => {
     return (
       <div>
         <oj-button id="createButton" onojAction={props.create}>Create</oj-button>
         <oj-button id="updateButton" disabled={hideActions} onojAction={props.edit}>Update</oj-button>
       </div>
    

    Guarde el archivo ItemActionsContainer.tsx. El código debe ser similar a ItemActionsContainer.tsx.txt

  5. En la parte superior del archivo EditItemDialog.tsx, importe los módulos de Oracle JET para el componente de diálogo más los enlaces de preferencia useRef, useEffect y useState.

    import { h } from "preact";
    import { useRef, useEffect, useState  } from "preact/hooks";
    import "ojs/ojdialog";
    import { ojDialog } from "ojs/ojdialog";
    
  6. En el alias de tipo Props, cree las siguientes propiedades.

     type Props = {
       isOpened: boolean;
       closeDialog: (ref, type:string) => void;
       editItem: (data:Partial<Item>,ref) => void;
       itemData: Partial<Item>;
     };
    
    
  7. En la sentencia return, sustituya el elemento div existente por un elemento span que encapsule el elemento personalizado oj-dialog.

    return (
      <span>
       <oj-dialog id="editDialog" ref={editDialogRef} dialogTitle="Update Item Details" onojClose={closeDialog} cancelBehavior="icon">
         <div slot="body">
           <oj-label-value labelEdge="inside">
             <oj-label for="itemid" slot="label">
               Item ID
             </oj-label>
             <div id="itemid" slot="value" class="slot-line">
               {editFormData?.id}
             </div>
           </oj-label-value>
           <oj-form-layout>
             <oj-input-text id="name" labelHint="Name" onvalueChanged={onChangeHandler} value={editFormData?.name}></oj-input-text>
             <oj-input-text id="price" labelHint="Price" onvalueChanged={onChangeHandler} value={editFormData?.price}></oj-input-text>
             <oj-input-text id="short_desc" labelHint="Description" 
                            onvalueChanged={onChangeHandler} value={editFormData?.short_desc}></oj-input-text>
           </oj-form-layout>
         </div>
         <div slot="footer">
           <oj-button id="submitBtn" onojAction={editItem}>
             Submit
           </oj-button>
         </div>
       </oj-dialog>
     </span>
    );
    
  8. Antes de la sentencia return, agregue los métodos que los valores de atributo de los elementos personalizados secundarios de la referencia de elemento personalizado oj-dialog. Por ejemplo, se llama al método onChangeHandler cuando un componente oj-input-text detecta un cambio a través de su atributo onvalueChanged.

    const EditItemDialog = (props: Props) => {
      const editDialogRef = useRef<ojDialog>(null);
      const [editFormData, setEditFormData] = useState<Partial<Item>>();
    
      const onChangeHandler = (event) => {
        if (event.detail.updatedFrom === "internal") {
          setEditFormData({
            ...editFormData,
            [event.currentTarget.id]: event.detail.value,
          });
        }
      };
    
      const closeDialog = () => {
        props.closeDialog(editDialogRef, "edit");
      };
    
      const editItem = () => {
        console.log("data: " + JSON.stringify(editFormData));
        props.editItem(editFormData, editDialogRef);
      };
    
      useEffect(() => {
        setEditFormData(props.itemData);
        props.isOpened ? editDialogRef.current?.open() : editDialogRef.current?.close();
      }, [props.isOpened]);
    
      return (
    
  9. Antes de la declaración de la función EditItemDialog, defina un alias de tipo Item que incluya campos para los datos que actualice y envíe al servicio REST.

    type Item = {
      id: number;
      name: string | undefined;
      short_desc?: string;
      price?: number;
      quantity?: number;
      quantity_shipped?: number;
      quantity_instock?: number;
      activity_id?: number;
      image?: string;
     };
    
     const EditItemDialog = (props: Props) => {
    

    Guarde el archivo EditItemDialog.tsx. El código debe ser similar a EditItemDialog.tsx.txt

Tarea 3: Consumir el componente EditItemDialog

  1. Abra el archivo ActivityItemContainer.tsx e importe el componente EditItemDialog que ha creado en la última tarea más el enlace MutableRef de Preact y el módulo de Oracle JET para el componente de diálogo.

    import EditItemDialog from "./EditItemDialog";	
    import { useState, useCallback, MutableRef } from "preact/hooks";
    import { ojDialog } from "ojs/ojdialog";
    
  2. En el alias de tipo Props, actualice la entrada de data para admitir el tipo any para RESTDataProvider y suprima o comente el tipo ActivityItem que el componente ya no utiliza.

    	type Props = {
      data?: RESTDataProvider<any, any>;
      selectedActivity?: Item;
      onItemChanged?: (item: any) => void;
    };
    
    // type ActivityItem = {
    //   id: number;
    //   name: string;
    //   items: Array<Item>;
    //   short_desc: string;
    //   image: string;
    // };
    
  3. En la sentencia return, actualice el elemento ItemActionsContainer con los valores de atributo itemSelected y edit. Después del elemento CreateNewItemDialog, agregue un nuevo elemento para el componente EditItemDialog que ha importado.

    	<div id="container">
        <h3>Activity Items</h3>
          <ItemActionsContainer create={openCreateDialog} itemSelected={activityItemValue} edit={openEditDialog} />
          . . . 
    </div>
    <CreateNewItemDialog isOpened={isCreateOpened} createNewItem={createItem} />
    <EditItemDialog isOpened={isEditOpened} editItem={editItem} closeDialog={handleDialogClose} itemData={itemData} />
     . . . 
    
  4. Antes de la sentencia return, agregue la función openEditDialog para abrir el cuadro de diálogo de edición y la función editItem para enviar el elemento de actividad actualizado al servicio REST.

    const openEditDialog = () => {
        console.log("Item: " + JSON.stringify(itemData));
        setIsEditOpened(true);
        console.log("Edit dialog opened");
      };
    
    const editItem = async (newItemData:Partial<Item>, editDialogRef: MutableRef<ojDialog>) => {
      if (newItemData != null) {
        const row = {
          itemId: newItemData.id,
          name: newItemData.name,
          price: newItemData.price,
          short_desc: newItemData.short_desc,
        };
    
        // Create and send request to update row on rest service
        const request = new Request(`${restServerURLItems}${itemData.id}`, {
          headers: new Headers({
            "Content-type": "application/json; charset=UTF-8",
          }),
          body: JSON.stringify(row),
          method: "PUT",
        });
        const response = await fetch(request);
        const updatedRow = await response.json();
    
        // Create update mutate event and call mutate method
        // to notify dataprovider consumers that a row has been
        // updated
        const updatedRowKey = itemData.id;
        const updatedRowMetaData = { key: updatedRowKey };
        props.data.mutate({
          update: {
            data: [updatedRow],
            keys: new Set([updatedRowKey]),
            metadata: [updatedRowMetaData],
          },
        });
      } // End if statement
        console.log("Edited item");
        editDialogRef.current.close();
      };
    
  5. En la función ActivityItemContainer, después de la declaración de variable restServerURLItems, utilice el enlace useState para asegurarse de que itemData haga referencia al elemento de actividad seleccionado.

    const ActivityItemContainer = (props: Props) => {
      const activityItemDataProvider = props.data;
      const restServerURLItems = "https://apex.oracle.com/pls/apex/oraclejet/lp/activities/" + props.selectedActivity.id + "/items/";
      const [itemData, setItemData] = useState<Item>(props.selectedActivity);
      . . .
    
  6. En la función selectedActivityItemChanged, agregue setItemData(tempItem) para llamar al enlace useState cada vez que cambie la actividad seleccionada.

    const selectedActivityItemChanged = useCallback(
      (event: ojListView.firstSelectedItemChanged<Item["id"], Item>) => {
        let tempItem = event.detail.value.data;
          if (tempItem != null) {
            props.onItemChanged(tempItem);
          } else {
            props.onItemChanged(null);
          }
          setActivityItemValue(tempItem);
          setItemData(tempItem);
        },
        [activityItemValue]
      );
    

    Guarde el archivo ActivityItemContainer.tsx. El código debe ser similar a ActivityItemContainer.tsx.txt

Tarea 4: probar el código y actualizar un registro

  1. En la ventana de terminal, cambie al directorio JET-Virtual-DOM-app y ejecute la aplicación DOM virtual.

    npx @oracle/ojet-cli serve
    
  2. En el explorador, visualice los cambios dinámicos en la aplicación DOM virtual.

  3. En la aplicación DOM virtual, haga clic en la actividad Baseball y, a continuación, haga clic en el elemento SureFire Ball (Set of 4).

  4. Haga clic en el botón Actualizar.

    Aparecerá el cuadro de diálogo Actualizar detalles de elemento.

  5. Cambie el precio de 20.5 a 21 y haga clic en Enviar.

    La sección se refresca y el precio del artículo se ha actualizado.

    Actualizar detalles de elemento

    Descripción de la ilustración update_record.png

  6. Cierre la ventana o el separador del explorador que muestra la aplicación DOM virtual en ejecución.

  7. En la ventana de terminal, pulse Ctrl+C y, si se le solicita, introduzca y para salir del trabajo por lotes de herramientas de Oracle JET.

Siguiente paso

Para continuar con el siguiente tutorial de esta ruta de aprendizaje, haga clic aquí.

Más recursos de aprendizaje

Explore otros laboratorios en docs.oracle.com/learn o acceda a más contenido de aprendizaje gratuito en el canal YouTube de Oracle Learning. Además, visite education.oracle.com/learning-explorer para convertirse en un explorador de Oracle Learning.

Para obtener documentación sobre el producto, visite Oracle Help Center.