Oracle JET 가상 DOM 앱에서 데이터 레코드 업데이트

소개

이 사용지침서에서는 Oracle JET(Oracle JavaScript Extension Toolkit) 가상 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: 대화 상자 열기 핸들

레코드를 갱신하는 기능이 포함된 EditItemDialog 구성 요소를 호출하도록 ItemActionsContainer 구성 요소의 유형과 함수를 선언합니다.

  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 대화상자 구성요소에 대한 모듈과 useRef, useEffect, MutableRefuseState 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 사용자정의 요소 참조의 하위 사용자정의 요소에 있는 속성 값을 지정하는 메소드를 추가합니다. 예를 들어, onChangeHandler 메소드는 oj-input-text 구성요소가 onvalueChanged 속성을 통해 변경사항을 감지할 때 호출됩니다.

     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 함수 선언 전에 업데이트하여 REST 서비스로 전송하는 데이터에 대한 필드를 포함하는 Item 유형 별칭을 정의합니다.

    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 후크 및 Dialog 구성요소에 대한 Oracle JET 모듈을 임포트합니다.

     import { useState, useCallback, MutableRef, useRef } from "preact/hooks";
     import EditItemDialog from "./EditItemDialog";
    
  2. Props 유형 별칭에서 data에 대한 항목을 업데이트하여 RESTDataProvider에 대한 any 유형을 지원하고 구성요소가 더 이상 사용하지 않는 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 문에서 ItemActionsContainer 요소를 itemSelectededit 속성 값으로 업데이트합니다. 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 (Set of 4) 항목을 누릅니다.
  4. 갱신 단추를 누릅니다.

    항목 세부 정보 업데이트 대화 상자가 나타납니다.

  5. 가격을 20.5에서 21로 변경하고 제출을 누릅니다.

    섹션이 새로 고쳐지고 품목 가격이 업데이트되었습니다.

    품목 상세내역 갱신

  6. 실행 중인 가상 DOM 앱을 표시하는 브라우저 창 또는 탭을 닫습니다.
  7. 터미널 창에서 Ctrl+C을 누르고 프롬프트가 표시되면 y를 입력하여 Oracle JET 툴링 일괄 처리 작업을 종료합니다.

다음단계

이 모듈의 다음 자습서로 이동합니다.

이 자습서는 REST 서비스를 사용한 CRUD 작업 모듈의 일부입니다.

가상 DOM 학습 경로의 기본 페이지로 돌아가 가상 DOM 앱 구축 시 모든 모듈에 액세스할 수 있습니다.

추가 학습 자원

docs.oracle.com/learn에서 다른 랩을 탐색하거나 Oracle Learning YouTube 채널에서 더 많은 무료 학습 콘텐츠에 액세스하세요. 또한 education.oracle.com/learning-explorer를 방문하여 Oracle Learning Explorer가 되십시오.

제품 설명서는 Oracle Help Center를 참조하십시오.