Oracle JET 가상 DOM 앱에서 데이터 레코드를 생성하는 폼을 생성합니다.

소개

이 사용지침서에서는 Oracle JET(Oracle JavaScript Extension Toolkit) 가상 DOM 앱을 사용하여 데이터 레코드를 생성하고 REST 서비스에 제출하는 방법을 보여줍니다.

목표

이 자습서에서는 REST 서비스에 데이터를 쓰는 방법에 대해 알아봅니다.

필수 조건

태스크 1: 폼 정보를 관리할 구성요소 생성

새 레코드를 생성하는 기능을 호출하는 데 사용되는 단추를 표시하는 새 구성요소를 생성합니다. ItemActionsContainer 구성 요소에는 가상 DOM 앱 사용자가 새 레코드를 생성하는 기능이 포함된 CreateNewItemDialog 구성 요소를 호출할 수 있는 버튼이 포함됩니다.

  1. JET-Virtual-DOM-app/src/components/ActivityItem 디렉토리로 이동하여 새 CreateNewItemDialog.tsx 파일을 생성하고 편집기에서 엽니다.

  2. 새 구성요소에 대한 함수 이름(CreateNewItemDialog)을 정의하는 위치 표시자 항목을 추가합니다.

    import { h } from 'preact';
    
    type Props = {
      message?: string;
    };
    
    const CreateNewItemDialog = (props: Props) => {
      return (
        <div class="oj-web-applayout-max-width oj-web-applayout-content">
          <p>content</p>
        </div>
      );
    };
    
    export default CreateNewItemDialog;
    
  3. 동일한 디렉토리에서 ItemActionsContainer.tsx 파일을 생성하고 편집기에서 엽니다.

  4. 새 구성요소에 대한 함수 이름(ItemActionsContainer)을 정의하는 위치 표시자 항목을 추가합니다.

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

작업 2: 대화 상자 열기 핸들

Oracle JET 모듈을 임포트하고 Oracle JET 가상 DOM 앱이 대화상자를 성공적으로 열 수 있도록 하는 기능을 선언합니다.

  1. 열린 ItemActionsContainer.tsx 파일의 맨 위에서 Button 구성 요소에 대한 Oracle JET 모듈을 임포트합니다.

    import { h } from 'preact';
    import 'ojs/ojbutton';
    
  2. Props 유형 별칭에서 create 속성을 정의하여 생성 대화상자 열기를 관리합니다.

    import { h } from 'preact';
    import 'ojs/ojbutton';
    
    type Props = {
      create: () => void;
    };
    
  3. return 문에서 기존 div 요소를 oj-button 요소를 create 속성을 참조하는 onojAction 속성으로 렌더링하는 새 div 요소로 바꿉니다.

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

    ItemActionsContainer.tsx 파일을 저장합니다. 코드는 ItemActionsContainer.tsx.txt과 유사해야 합니다.

  4. 열려 있는 CreateNewItemDialog.tsx 파일의 맨 위에서 대화상자 구성요소 및 MutableRef 후크에 대한 Oracle JET 모듈을 임포트합니다.

    import { h } from 'preact';
    import 'ojs/ojdialog';
    import { ojDialog } from 'ojs/ojdialog';
    import { MutableRef } from 'preact/hooks';
    
  5. Props 유형 별칭에 isOpenedcloseDialog 속성을 정의합니다.

    type Props = {
      isOpened: boolean;
      closeDialog: (ref: MutableRef<ojDialog>, type: string) => void;
    };
    
  6. return 문에서 기존 div 요소를 oj-dialog 사용자 정의 요소를 래핑하는 span 요소로 바꿉니다.

       return (
       <span>
          <oj-dialog id="createDialog" ref={createDialogRef} dialogTitle="Create New Item" onojClose={closeDialog} cancelBehavior="icon">
             <div slot="body">
             <p>dialog open</p>
             </div>
          </oj-dialog>
       </span>
       );
    
  7. CreateNewItemDialog.tsx 파일의 맨 위에서 useRefuseEffect Preact 후크를 가져옵니다.

    import { h } from 'preact';
    import { useRef, useEffect } from 'preact/hooks';
    import 'ojs/ojdialog';
    import { ojDialog } from 'ojs/ojdialog';
    
  8. return 문 앞에 useRef Preact 후크가 검색하는 참조를 보유할 createDialogRefcloseDialog 변수를 선언합니다.

    const CreateNewItemDialog = (props: Props) => {
    
       const createDialogRef = useRef<ojDialog>(null);
    
       const closeDialog = () => {
          props.closeDialog(createDialogRef as MutableRef<ojDialog>, "create");
        }
    
     return (
    	
    
  9. 또한 return 문 앞에 useEffect 후크를 사용하여 isOpened 속성에 대한 값을 설정하는 표현식을 작성합니다.

     const CreateNewItemDialog = (props: Props) => {
         const createDialogRef = useRef<ojDialog>(null);
    
         const closeDialog = () => {
         props.closeDialog(createDialogRef as MutableRef<ojDialog>, "create");
         }
    
         useEffect(() => {
          props.isOpened
             ? createDialogRef.current?.open()
             : createDialogRef.current?.close();
         }, [props.isOpened]);
    
     return (
    
    

    CreateNewItemDialog.tsx 파일을 저장합니다. 코드는 CreateNewItemDialog-1.tsx.txt과 유사해야 합니다.

  10. JET-Virtual-DOM-app/src/components/ActivityItem 디렉토리로 이동하여 ActivityItemContainer.tsx 파일을 엽니다.

  11. ActivityItemContainer.tsx 상단에서 방금 생성한 ItemActionsContainerCreateNewItemDialog 구성요소를 임포트하고 Oracle JET 폼 레이아웃 및 입력 텍스트 구성요소에 대한 모듈도 임포트합니다.

    import ItemActionsContainer from "./ItemActionsContainer";
    import CreateNewItemDialog from "./CreateNewItemDialog";
    import "ojs/ojformlayout";
    import "ojs/ojinputtext";
    import { ojDialog } from "ojs/ojdialog";
    import { MutableRef} from "preact/hooks"
    
  12. ActivityItemContainer 함수 선언 뒤에 Preact의 useState 후크와 함수(openCreateDialog)를 사용하여 대화상자를 여는 변수를 생성합니다.

    또한 이후 자습서에서 작성한 편집 대화상자의 열기 상태를 관리하는 항목도 포함합니다.

    const ActivityItemContainer = (props: Props) => {
     const [isCreateOpened, setIsCreateOpened] = useState<boolean>(false);
     const [isEditOpened, setIsEditOpened] = useState<boolean>(false);
    
      const openCreateDialog = () => {
         console.log("CreateNewItemDialog called");
         setIsCreateOpened(true);
      };
    
  13. return 문 앞에 열린 대화상자를 닫는 함수도 포함합니다.

    const handleDialogClose = (ref: MutableRef<ojDialog>, type: string) => {
       type === "create" ? setIsCreateOpened(false) : setIsEditOpened(false);
       ref.current.close();
    };
    
    return (
       <div id="activityItemsContainer" class=. . .>
    
  14. return 문에 새로 생성된 ItemActionsContainerCreateNewItemDialog 구성요소를 포함합니다.

    return (
    <div id="activityItemsContainer" . . .>
     <div id="container">
       <h3>Activity Items</h3>
        <ItemActionsContainer create={openCreateDialog} />
        <CreateNewItemDialog isOpened={isCreateOpened} closeDialog={handleDialogClose} />
    

    ActivityItemContainer.tsx 파일을 저장합니다. 코드는 ActivityItemContainer-1.tsx.txt과 유사해야 합니다.

작업 3: 대화상자 입력 제출 처리

  1. JET-Virtual-DOM-app/src/components/ActivityItem 디렉토리로 이동하여 CreateNewItemDialog.tsx 파일을 엽니다.

  2. 열린 CreateNewItemDialog.tsx 파일의 맨 위에서 Preact의 useState 후크를 가져옵니다.

    import { ojDialog } from 'ojs/ojdialog';
    import { MutableRef, useRef, useEffect, useState } from "preact/hooks"
    
  3. Props 유형 별칭에서 createNewItem 속성을 정의합니다.

    type Props = {
         isOpened: boolean;
         closeDialog: (ref: MutableRef<ojDialog>, type: string) => void;
         createNewItem: (data: Partial<Item>, ref: MutableRef<ojDialog>) => void;
     };
    
  4. REST 서비스로 전송하는 데이터에 대한 필드가 포함된 Item 유형 별칭을 정의합니다.

    type Item = {
      name?: string | undefined;
      short_desc?: string;
      price?: number;
      quantity_shipped?: number;
      quantity_instock?: number;
    };
    
  5. return 문에서 oj-dialog 사용자정의 요소를 찾아 새 항목을 생성하기 위해 입력 필드에 대한 <div slot="body"> 콘텐츠를 oj-form-layout 요소 및 oj-input-text 요소로 바꿉니다. oj-button 요소와 함께 <div slot="footer">도 포함합니다.

    <oj-dialog id="createDialog" ref={createDialogRef} dialogTitle="Create New Item" onojClose={closeDialog} cancelBehavior="icon">
        <div slot="body">
           <oj-form-layout>
           <oj-input-text id="name" labelHint="Name" onvalueChanged={onChangeHandler}></oj-input-text>
           <oj-input-text id="price" labelHint="Price" onvalueChanged={onChangeHandler}></oj-input-text>
           <oj-input-text id="short_desc" labelHint="Description" onvalueChanged={onChangeHandler}></oj-input-text>
           <oj-input-text id="quantity_instock" labelHint="Quantity: In-Stock" onvalueChanged={onChangeHandler}></oj-input-text>
           <oj-input-text id="quantity_shipped" labelHint="Quantity: Shipped" onvalueChanged={onChangeHandler}></oj-input-text>
           </oj-form-layout>
        </div>
        <div slot="footer">
           <oj-button id="submitBtn" onojAction={createItem}>Submit</oj-button>
        </div>
     </oj-dialog>
    
  6. return 문 앞에 useState 후크를 사용하고 Oracle JET 요소가 참조하는 onChangeHandercreateItem 함수를 포함합니다.

    const [formData, setFormData] = useState<Partial<Item>>({});
    
     const onChangeHandler = (event: any) => {
        setFormData({
           ...formData,
           [event.currentTarget.id]: event.detail.value,
        });
     }
    
     const createItem = () => {
        console.log("data: " + JSON.stringify(formData));
        props.createNewItem(formData, createDialogRef as MutableRef<ojDialog>);
     };
    
     return (
       <span>. . .
    

    CreateNewItemDialog.tsx 파일을 저장합니다. 코드는 CreateNewItemDialog-2.tsx.txt과 유사해야 합니다.

  7. JET-Virtual-DOM-app/src/components/ActivityItem 디렉토리로 이동하여 ActivityItemContainer.tsx 파일을 엽니다.

  8. return 문에서 CreateNewItemDialog 구성요소에 정의한 createNewItem 메소드를 포함하도록 CreateNewItemDialog 클래스를 업데이트합니다.

    <CreateNewItemDialog isOpened={isCreateOpened} createNewItem={createItem} closeDialog={handleDialogClose} />
    
  9. return 문 앞에 새 항목을 생성하고 백엔드 REST 서비스로 전송하는 새 createItem 함수를 포함하십시오.

    const createItem = async (data: Partial<Item>, createDialogRef: MutableRef<ojDialog>) => {
      //process create command and close dialog on success
      if (data?.name) {
         let quantity = Number(data.quantity_instock) + Number(data.quantity_shipped);
         const row = {
           name: data.name,
           short_desc: data.short_desc,
           price: data.price,
           quantity_instock: data.quantity_instock,
           quantity_shipped: data.quantity_shipped,
           quantity: quantity,
           activity_id: props.selectedActivity?.id,
           image: "css/images/product_images/jet_logo_256.png",
         };
    
         // Create and send request to REST service to add row
         const request = new Request(restServerURLItems, {
           headers: new Headers({
             "Content-type": "application/json; charset=UTF-8",
           }),
           body: JSON.stringify(row),
           method: "POST",
         });
    
         const response = await fetch(request);
         const addedRow = await response.json();
    
         activityItemDataProvider?.refresh();
         // Close dialog
         console.log("Created new item");
         createDialogRef.current.close();
       }
     };
    
  10. ActivityItemContainer 함수 선언 뒤에 항목을 REST 서비스로 전송하는 데 사용할 URL을 참조하는 변수를 정의합니다.

    const ActivityItemContainer = (props: Props) => {
        const activityItemDataProvider = props.data;
        const restServerURLItems = "https://apex.oracle.com/pls/apex/oraclejet/lp/activities/" + props.selectedActivity?.id + "/items/";
    
  11. ActivityItemContainer.tsx 파일을 저장합니다. 코드는 ActivityItemContainer-2.tsx.txt과 유사해야 합니다.

작업 4: 코드 테스트 및 레코드 생성

  1. 터미널 창에서 JET-Virtual-DOM-app 디렉토리로 변경하고 가상 DOM 앱을 실행합니다.

    npx ojet serve
    
  2. 브라우저에서 가상 DOM 앱의 동적 변경사항을 확인합니다.
  3. 가상 DOM 앱에서 Baseball 작업을 누릅니다.
  4. Create를 누릅니다.

    새 항목 생성 대화상자가 열립니다.

  5. 새 항목에 대한 세부 정보를 입력합니다.

    • 이름: SureFire Ball (Set of 4)
    • 가격: 20.5
    • 설명: Canvas balls for practice
    • 수량: 재고 있음: 35
    • 수량: 출하됨: 61
  6. 제출을 누릅니다.

    섹션이 새로 고쳐지고 항목이 야구 활동 항목 목록의 일부입니다.

  7. 목록에서 SureFire Ball (Set of 4) 항목을 누르고 세부정보를 봅니다.

    새 품목 생성 대화상자

  8. 실행 중인 가상 DOM 앱을 표시하는 브라우저 창 또는 탭을 닫습니다.

  9. 터미널 창에서 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를 참조하십시오.