更新 Oracle JET 虚拟 DOM 应用程序中的数据记录
简介
此教程演示如何使用 Oracle JavaScript Extension Toolkit (Oracle JET) 虚拟 DOM 应用程序更新现有数据记录并将其提交到 REST 服务。
目标
在本教程中,您将学习如何更新现有数据记录并将其提交到 REST 服务。
Prerequisites
- 设置为创建包括 Node.js 安装的 Oracle JET 虚拟 DOM 应用程序的开发环境
- 完成此学习路径中的上一个教程,创建表单以在 Oracle JET 虚拟 DOM 应用程序中创建数据记录
任务 1:创建用于管理表单信息的组件
创建一个新组件,该组件将显示一个对话框以调用更新记录的功能。
-
导航到
JET-Virtual-DOM-app/src/components/ActivityItem
目录,创建新的EditItemDialog.tsx
文件,然后在编辑器中将其打开。 -
添加为新组件定义函数名称 (
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
组件。
-
导航到
JET-Virtual-DOM-app/src/components/ActivityItem
目录并打开ItemActionsContainer.tsx
文件。 -
在文件顶部,导入
useState
和useEffect
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; };
-
在
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 (
-
在
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
-
在
EditItemDialog.tsx
文件的顶部,导入 Oracle JET Dialog 组件以及useRef
、useEffect
、MutableRef
和useState
Preact 挂钩的模块。import { h } from "preact"; import { useRef, useEffect, useState, MutableRef } from "preact/hooks"; import "ojs/ojdialog"; import { ojDialog } from "ojs/ojdialog";
-
在
Props
类型别名中,创建以下属性。type Props = { isOpened: boolean; closeDialog: (ref: MutableRef<ojDialog>, type: string) => void; editItem: (data: Partial<Item>, ref: MutableRef<ojDialog>) => void; itemData: Partial<Item>; };
-
在
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> );
-
在
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 (
-
在声明
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 组件
-
打开
ActivityItemContainer.tsx
文件并导入您在上一个任务中创建的EditItemDialog
组件以及 Preact 的MutableRef
挂钩和 Dialog 组件的 Oracle JET 模块。import { useState, useCallback, MutableRef, useRef } from "preact/hooks"; import EditItemDialog from "./EditItemDialog";
-
在
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; // };
-
在
return
语句中,使用itemSelected
和edit
属性值更新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} /> . . .
-
在
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:测试代码并更新记录
-
在终端窗口中,转到
JET-Virtual-DOM-app
目录并运行虚拟 DOM 应用程序。npx ojet serve
- 在浏览器中,查看虚拟 DOM 应用程序中的动态更改。
- 在虚拟 DOM 应用程序中,单击 Baseball 活动,然后单击 SureFire Ball (Set of 4) 项。
-
单击更新按钮。
此时将弹出 "Update Item Details" 对话框。
-
将价格从
20.5
更改为21
,然后单击提交。区段将刷新,并且货品的价格已更新。
- 关闭显示正在运行的虚拟 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 帮助中心。
Update data records in an Oracle JET virtual DOM app
F70663-02