创建表单以在 Oracle JET 虚拟 DOM 应用程序中创建数据记录
简介
此教程演示如何使用 Oracle JavaScript Extension Toolkit (Oracle JET) 虚拟 DOM 应用程序创建数据记录并将其提交到 REST 服务。
目标
在本教程中,您将学习如何将数据写入到 REST 服务。
Prerequisites
- 设置为创建包括 Node.js 安装的 Oracle JET 虚拟 DOM 应用程序的开发环境
- 完成此学习路径中的上一个教程,在 Oracle JET 虚拟 DOM 应用程序中从 REST API 提取数据
任务 1:创建用于管理表单信息的组件
创建新组件,以显示用于调用创建新记录的功能按钮。ItemActionsContainer 组件包含允许虚拟 DOM 应用程序用户调用包含创建新记录的功能的 CreateNewItemDialog 组件的按钮。
-
导航到
JET-Virtual-DOM-app/src/components/ActivityItem目录,创建新的CreateNewItemDialog.tsx文件,然后在编辑器中将其打开。 -
添加为新组件定义函数名称 (
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; -
在同一目录中,创建
ItemActionsContainer.tsx文件并在编辑器中将其打开。 -
添加为新组件定义函数名称 (
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 应用程序能够成功打开对话框的功能。
-
在打开的
ItemActionsContainer.tsx文件的顶部,导入按钮组件的 Oracle JET 模块。import { h } from 'preact'; import 'ojs/ojbutton'; -
在
Props类型别名中定义create属性以管理打开创建对话框。import { h } from 'preact'; import 'ojs/ojbutton'; type Props = { create: () => void; }; -
在
return语句中,将现有div元素替换为新的div元素,该元素使用引用create属性的onojAction属性呈现oj-button元素。const ItemActionsContainer = (props: Props) => { return ( <div> <oj-button id="createButton" onojAction={props.create}> Create </oj-button> </div>保存
ItemActionsContainer.tsx文件。您的代码应类似于ItemActionsContainer.tsx.txt -
在打开的
CreateNewItemDialog.tsx文件的顶部,导入 Dialog 组件的 Oracle JET 模块和MutableRef挂钩。import { h } from 'preact'; import 'ojs/ojdialog'; import { ojDialog } from 'ojs/ojdialog'; import { MutableRef } from 'preact/hooks'; -
在
Props类型别名中定义isOpened和closeDialog属性。type Props = { isOpened: boolean; closeDialog: (ref: MutableRef<ojDialog>, type: string) => void; }; -
在
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> ); -
在
CreateNewItemDialog.tsx文件的顶部,导入useRef和useEffectPreact 钩子。import { h } from 'preact'; import { useRef, useEffect } from 'preact/hooks'; import 'ojs/ojdialog'; import { ojDialog } from 'ojs/ojdialog'; -
在
return语句之前,声明createDialogRef和closeDialog变量,这些变量将保存useRefPreact 挂钩检索到的引用。const CreateNewItemDialog = (props: Props) => { const createDialogRef = useRef<ojDialog>(null); const closeDialog = () => { props.closeDialog(createDialogRef as MutableRef<ojDialog>, "create"); } return ( -
在
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 -
导航到
JET-Virtual-DOM-app/src/components/ActivityItem目录并打开ActivityItemContainer.tsx文件。 -
在
ActivityItemContainer.tsx的顶部,导入刚创建的ItemActionsContainer和CreateNewItemDialog组件,同时导入 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" -
在
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); }; -
在
return语句之前,还应包括关闭打开对话框的函数。const handleDialogClose = (ref: MutableRef<ojDialog>, type: string) => { type === "create" ? setIsCreateOpened(false) : setIsEditOpened(false); ref.current.close(); }; return ( <div id="activityItemsContainer" class=. . .> -
在
return语句中,包括新创建的ItemActionsContainer和CreateNewItemDialog组件。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:处理提交对话框输入
-
导航到
JET-Virtual-DOM-app/src/components/ActivityItem目录并打开CreateNewItemDialog.tsx文件。 -
在打开的
CreateNewItemDialog.tsx文件的顶部,导入 Preact 的useState钩子。import { ojDialog } from 'ojs/ojdialog'; import { MutableRef, useRef, useEffect, useState } from "preact/hooks" -
在
Props类型别名中,定义createNewItem属性。type Props = { isOpened: boolean; closeDialog: (ref: MutableRef<ojDialog>, type: string) => void; createNewItem: (data: Partial<Item>, ref: MutableRef<ojDialog>) => void; }; -
定义
Item类型别名,其中包含您发送到 REST 服务的数据的字段。type Item = { name?: string | undefined; short_desc?: string; price?: number; quantity_shipped?: number; quantity_instock?: number; }; -
在
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> -
在
return语句之前,使用useState钩子并包括 Oracle JET 元素引用的onChangeHander和createItem函数。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 -
导航到
JET-Virtual-DOM-app/src/components/ActivityItem目录并打开ActivityItemContainer.tsx文件。 -
在
return语句中,更新CreateNewItemDialog类以包括您在CreateNewItemDialog组件中定义的createNewItem方法。<CreateNewItemDialog isOpened={isCreateOpened} createNewItem={createItem} closeDialog={handleDialogClose} /> -
在
return语句之前,包括一个新的createItem函数,用于创建新项并将其发送到后端 REST 服务。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(); } }; -
在
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/"; -
保存
ActivityItemContainer.tsx文件。您的代码应类似于ActivityItemContainer-2.tsx.txt
任务 4:测试代码并创建记录
-
在终端窗口中,转到
JET-Virtual-DOM-app目录并运行虚拟 DOM 应用程序。npx ojet serve - 在浏览器中,查看虚拟 DOM 应用程序中的动态更改。
- 在虚拟 DOM 应用程序中,单击 Baseball 活动。
-
单击创建。
此时将打开创建新项对话框。
-
填写新商品的详细信息。
- 名称:
SureFire Ball (Set of 4) - 价格:
20.5 - 说明:
Canvas balls for practice - 数量:库存:
35 - 数量:已发运:
61
- 名称:
-
单击提交。
区段将刷新,该项是棒球活动项列表的一部分。
-
单击列表中的 SureFire Ball (Set of 4) 项并查看其详细信息。

-
关闭显示正在运行的虚拟 DOM 应用程序的浏览器窗口或选项卡。
- 在终端窗口中,按 Ctrl+C,如果出现提示,输入
y以退出 Oracle JET 工具批处理作业。
后续步骤
本教程是 CRUD Operations Using a REST Service 模块的一部分。
- 从 Oracle JET 中的 REST API 提取数据
- 创建表单以在 Oracle JET 虚拟 DOM 应用程序中创建数据记录
- 在 Oracle JET 虚拟 DOM 应用程序中更新数据记录
- 删除 Oracle JET 虚拟 DOM 应用程序中的数据记录
您可以返回到虚拟 DOM 学习路径的主页,以访问有关构建虚拟 DOM 应用程序的所有模块。
更多学习资源
通过 docs.oracle.com/learn 浏览其他实验室,或者通过 Oracle Learning YouTube 频道访问更多免费学习内容。此外,请访问 education.oracle.com/learning-explorer 以成为 Oracle Learning Explorer。
有关产品文档,请访问 Oracle 帮助中心。
Create a form to create data records in an Oracle JET virtual DOM app
F70655-02