更新 Oracle JET 虛擬 DOM App 中的資料記錄

簡介

本教學課程示範如何使用 Oracle JavaScript Extension Toolkit (Oracle JET) 虛擬 DOM 應用程式來更新現有資料記錄,然後將它送出至 REST 服務。

目標

在本教學課程中,您將瞭解如何更新現有的資料記錄,並將其提交至 REST 服務。

必備條件

作業 1:建立管理表單資訊的元件

建立將顯示對話方塊的新元件,以呼叫更新記錄的功能。

  1. 瀏覽至 JET-Virtual-DOM-app/src/components/ActivityItem 目錄,建立新的 EditItemDialog.tsx 檔案,然後在編輯器中開啟該檔案。

  2. 新增定義新元件之函數名稱 (EditItemDialog) 的預留位置項目。

    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;
    

工作 2:處理開啟對話方塊

宣告 ItemActionsContainer 元件中的類型和函數,以呼叫包含更新記錄功能之 EditItemDialog 元件。

  1. 瀏覽至 JET-Virtual-DOM-app/src/components/ActivityItem 目錄,然後開啟 ItemActionsContainer.tsx 檔案。

  2. 在檔案頂端,匯入 useStateuseEffect Preact 鉤點,在您需要使用 EditItemDialog 元件的 Props 類型別名中定義其他特性,然後定義 Item 類型別名。

     import { h } from "preact";
     import "ojs/ojbutton";
     import { useState, useEffect } from "preact/hooks";
    
     type Props = {
         create: () => void;
         edit: () => void;
         itemSelected: Partial<Item>;
     };
    
     type Item = {
         id: number;
         name: string;
         short_desc?: string;
         price?: number;
         quantity?: number;
         quantity_shipped?: number;
         quantity_instock?: number;
         activity_id?: number;
         image?: string;
     };
    
  3. return 陳述式之前,請使用您匯入的 Preact 鉤點來判斷是否已選取活動項目。

     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. return 敘述句中,新增含有參照 edit 特性之 onojAction 屬性的 oj-button 元素。

    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>
    

    儲存 ItemActionsContainer.tsx 檔案。您的程式碼應該與 ItemActionsContainer.tsx.txt 類似

  5. EditItemDialog.tsx 檔案頂端,匯入「Oracle JET 對話方塊」元件的模組,以及 useRefuseEffectMutableRefuseState Preact 鉤點。

    import { h } from "preact";
    import { useRef, useEffect, useState, MutableRef  } from "preact/hooks";
    import "ojs/ojdialog";
    import { ojDialog } from "ojs/ojdialog";
    
  6. Props 類型別名中,建立下列特性。

    type Props = {
       isOpened: boolean;
       closeDialog: (ref: MutableRef<ojDialog>, type: string) => void;
       editItem: (data: Partial<Item>, ref: MutableRef<ojDialog>) => void;
       itemData: Partial<Item>;
     };
    
  7. return 陳述式中,將現有的 div 元素取代為包裝 oj-dialog 自訂元素的 span 元素。

     return (
         <span>
         <oj-dialog id="editDialog" ref={editDialogRef as MutableRef<ojDialog>} 
                     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. return 敘述句之前,新增屬性值在 oj-dialog 自訂元素參照之子項自訂元素中的方法。例如,當 oj-input-text 元件透過其 onvalueChanged 屬性偵測變更時,會呼叫 onChangeHandler 方法。

     const EditItemDialog = (props: Props) => {
         const editDialogRef = useRef<ojDialog>();
         const [editFormData, setEditFormData] = useState<Partial<Item>>({});
    
         const onChangeHandler = (event: any) => {
         if (event.detail.updatedFrom === "internal") {
             setEditFormData({
             ...editFormData,
             [event.currentTarget.id]: event.detail.value,
             });
         }
         };
    
         const closeDialog = () => {
         props.closeDialog(editDialogRef as MutableRef<ojDialog>, "edit");
         };
    
         const editItem = () => {
         console.log("data: " + JSON.stringify(editFormData));
         props.editItem(editFormData, editDialogRef as MutableRef<ojDialog>);
         };
    
         useEffect(() => {
         setEditFormData(props.itemData);
         props.isOpened ? editDialogRef.current?.open() : editDialogRef.current?.close();
         }, [props.isOpened]);
    
         return (
    
    
  9. 在宣告 EditItemDialog 函數之前,請先定義 Item 類型別名,其中包含您更新並傳送至 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) => {
    

    儲存 EditItemDialog.tsx 檔案。您的程式碼應該與 EditItemDialog.tsx.txt 類似

工作 3:使用 EditItemDialog 元件

  1. 開啟 ActivityItemContainer.tsx 檔案,然後匯入您在最後一個工作中建立的 EditItemDialog 元件,再加上 Preact 的 MutableRef 鉤點,以及對話方塊元件的 Oracle JET 模組。

     import { useState, useCallback, MutableRef, useRef } from "preact/hooks";
     import EditItemDialog from "./EditItemDialog";
    
  2. Props 類型別名中,更新 data 的項目以支援 RESTDataProviderany 類型,然後刪除或註解元件不再使用的 ActivityItem 類型。

     type Props = {
       data?: RESTDataProvider<any, any>;
       selectedActivity: Item | null;
      	  onItemChanged: (item: Item) => void;
     };
    
    // type ActivityItem = {
     //   id: number;
     //   name: string;
     //   items: Array<Item>;
     //   short_desc: string;
     //   image: string;
     // };
    
  3. return 敘述句中,以 itemSelectededit 屬性值更新 ItemActionsContainer 元素。在 CreateNewItemDialog 元素之後,新增您匯入之 EditItemDialog 元件的新元素。

     <div id="container">
         <h3>Activity Items</h3>
           <ItemActionsContainer create={openCreateDialog} itemSelected={activityItemValue} edit={openEditDialog} />
           . . . 
    </div>
     <CreateNewItemDialog isOpened={isCreateOpened} createNewItem={createItem} closeDialog={handleDialogClose} />
     <EditItemDialog isOpened={isEditOpened} editItem={editItem} closeDialog={handleDialogClose} itemData={itemData} />
      . . . 
    
  4. return 陳述式之前,新增 openEditDialog 函數以開啟編輯對話方塊,並新增 editItem 函數以將更新的活動項目傳送至 REST 服務。

     const openEditDialog = () => {
         console.log("Item: " + JSON.stringify(itemData));
         setIsEditOpened(true);
         console.log("Edit dialog opened");
         };
    
     const editItem = async (newItemData:Partial<Item>, editDialogRef = useRef<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();
         };
    
    

    儲存 ActivityItemContainer.tsx 檔案。您的程式碼應該與 ActivityItemContainer.tsx.txt 類似

任務 4:測試程式碼並更新記錄

  1. 在終端機視窗中,變更為 JET-Virtual-DOM-app 目錄,然後執行虛擬 DOM 應用程式。

     npx ojet serve
    
  2. 在瀏覽器中,檢視虛擬 DOM 應用程式中的動態變更。
  3. 在虛擬 DOM 應用程式中,按一下 Baseball 活動,然後按一下 SureFire Ball (4 組) 項目。
  4. 按一下更新按鈕。

    「更新項目詳細資料」對話方塊即會出現。

  5. 將價格從 20.5 變更為 21,然後按一下提交

    區段會重新整理,且項目價格已更新。

    更新料號明細

  6. 關閉顯示您執行中虛擬 DOM 應用程式的瀏覽器視窗或頁籤。
  7. 在終端機視窗中,按 Ctrl+C,如果出現提示,請輸入 y 以結束 Oracle JET 工具批次工作。

下一步

繼續本模組的下一個教學課程。

本教學課程是 CRUD Operations Using a REST Service 模組的一部分。

您可以返回虛擬 DOM 學習路徑的主頁面,存取建置虛擬 DOM 應用程式的所有模組。

其他學習資源

docs.oracle.com/learn 上探索其他實驗室,或在 Oracle Learning YouTube 頻道上存取更多免費學習內容。此外,請造訪 education.oracle.com/learning-explorer 以成為 Oracle Learning Explorer。

如需產品文件,請造訪 Oracle Help Center