家校通小程序实战教程10部门管理前后端连接

目录

  • 1 加载后端的数据
  • 2 为什么不直接给变量赋值
  • 3 保存部门信息
  • 4 最终的效果
  • 5 总结

现在部门管理已经完成了后端功能和前端开发,就需要在前端调用后端的数据完成界面的展示,而且在录入部门信息后需要提交到数据库里,本篇我们介绍一下前后端如何交互。

1 加载后端的数据

现在后端API已经有了,页面加载的时候需要从后端读取数据。打开应用,点击编辑JSX代码

在这里插入图片描述
输入如下代码

export default function DepartmentTree(props: JSXCompProps) {const { $w, contentSlot1, style } = props;const { Modal, Input, Tree, Button, Form } = antd;const [treeData, setTreeData] = React.useState([]);const [selectedNode, setSelectedNode] = React.useState(null);const [addChildModalVisible, setAddChildModalVisible] = React.useState(false);const [newDepartmentName, setNewDepartmentName] = React.useState("");const [contextMenuTargetId, setContextMenuTargetId] = React.useState(null);const [contextMenuPosition, setContextMenuPosition] = React.useState(null);const [form] = Form.useForm();// 初始化获取部门数据React.useEffect(() => {async function fetchDepartments() {try {const result = await $w.cloud.callDataSource({dataSourceName: "departmentManagement_adpurdw",methodName: "getAllDepartments",params: {}});if (result && result.data) {setTreeData(result.data);} else {Modal.warning({ title: "数据加载失败", content: "未获取到部门数据。" });}} catch (error) {console.error("Error fetching departments:", error);Modal.error({ title: "加载失败", content: "获取部门数据时出错,请稍后重试。" });}}fetchDepartments();}, [$w]);// 点击节点事件const handleNodeClick = (node) => {setSelectedNode(node);setContextMenuTargetId(null);form.setFieldsValue({ name: node.name });};// 切换节点展开/收起const toggleNode = (node) => {node.isOpen = !node.isOpen;setTreeData([...treeData]);};// 递归更新树节点const updateTree = (nodes, callback) => {return nodes.map((node) => {if (callback(node)) {return { ...node };}if (node.children) {return { ...node, children: updateTree(node.children, callback) };}return node;});};// 添加子部门逻辑const handleAddChild = () => {if (!newDepartmentName.trim()) {return Modal.warning({title: "部门名称不能为空",content: "请输入部门名称后重试。"});}const newChild = {id: Date.now(),name: newDepartmentName,parentId: contextMenuTargetId,children: [],isOpen: false};setTreeData((prevTreeData) =>updateTree(prevTreeData, (node) => {if (node.id === contextMenuTargetId) {node.children = [...(node.children || []), newChild];return true;}return false;}));setAddChildModalVisible(false);setNewDepartmentName("");};// 保存表单修改const handleSaveForm = () => {form.validateFields().then((values) => {setTreeData((prevTreeData) =>updateTree(prevTreeData, (node) => {if (node.id === selectedNode.id) {node.name = values.name;return true;}return false;}));Modal.success({ title: "保存成功", content: "部门信息已更新。" });}).catch((info) => console.error("Validate Failed:", info));};// 右键点击事件const handleRightClick = (e, node) => {e.preventDefault();setContextMenuTargetId(node.id);setContextMenuPosition({ x: e.clientX, y: e.clientY });};// 渲染树节点const renderTree = (nodes) =>nodes.map((node) => (<Tree.TreeNodekey={node.id}title={<spanonClick={() => handleNodeClick(node)}onContextMenu={(e) => handleRightClick(e, node)}>{node.name}</span>}>{node.children && renderTree(node.children)}</Tree.TreeNode>));return (<div style={{ display: "flex", ...style }}>{/* 左侧树 */}<divstyle={{flex: "1",borderRight: "1px solid #ddd",overflowY: "auto",padding: "10px",minHeight: "300px"}}><Tree showLine defaultExpandAll>{renderTree(treeData)}</Tree></div>{/* 右侧表单 */}<divstyle={{flex: "2",padding: "10px",minHeight: "300px"}}>{selectedNode ? (<Form form={form} layout="vertical"><h3>部门信息</h3><Form.Itemlabel="部门名称"name="name"rules={[{ required: true, message: "请输入部门名称" }]}><Input /></Form.Item><Form.Item label="部门编号"><Input value={selectedNode.id} disabled /></Form.Item><div style={{ marginTop: "10px" }}><Buttontype="primary"onClick={handleSaveForm}style={{ marginRight: "10px" }}>保存</Button><Button onClick={() => form.resetFields()}>取消</Button></div></Form>) : (<p>请选择左侧树节点以查看或编辑部门信息。</p>)}</div>{/* 添加子部门 Modal */}<Modaltitle="添加子部门"visible={addChildModalVisible}onOk={handleAddChild}onCancel={() => setAddChildModalVisible(false)}><Inputplaceholder="请输入部门名称"value={newDepartmentName}onChange={(e) => setNewDepartmentName(e.target.value)}/></Modal>{/* 右键菜单 */}{contextMenuPosition && (<divstyle={{position: "absolute",top: contextMenuPosition.y,left: contextMenuPosition.x,backgroundColor: "#fff",boxShadow: "0 2px 8px rgba(0,0,0,0.15)",borderRadius: "4px",zIndex: 1000}}onMouseLeave={() => setContextMenuPosition(null)}><divonClick={() => setAddChildModalVisible(true)}style={{padding: "8px 16px",cursor: "pointer",borderBottom: "1px solid #f0f0f0"}}>添加子部门</div></div>)}{/* 插槽 */}<div>{contentSlot1}</div></div>);
}

我们追加了一个代码,主要是要异步调用后端API的

  // 初始化获取部门数据React.useEffect(() => {async function fetchDepartments() {try {const result = await $w.cloud.callDataSource({dataSourceName: "departmentManagement_adpurdw",methodName: "getAllDepartments",params: {}});if (result && result.data) {setTreeData(result.data);} else {Modal.warning({ title: "数据加载失败", content: "未获取到部门数据。" });}} catch (error) {console.error("Error fetching departments:", error);Modal.error({ title: "加载失败", content: "获取部门数据时出错,请稍后重试。" });}}fetchDepartments();}, [$w]);

这里的dataSourceName和methodName是从我们的API里获取的
在这里插入图片描述
部门管理旁边的相当于我们的dataSourceName,而标识相当于我们的methodName

2 为什么不直接给变量赋值

我一开始认为,我直接获取数据就可以,比如这样

const treeData = $w.cloud.callDataSource({dataSourceName: "departmentManagement_adpurdw",methodName: "getAllDepartments",params: {}
});

但这种操作发现树是空的,并没有从后台读取数据过来。主要的原因是两方面,首先callDataSource是异步的,你这个执行完了数据其实是没返回的

两一方面,数据加载完毕并不会通知React重新渲染组件。改成useEffect的好处是,在组件首次渲染后启动数据加载任务。当数据加载完成后,通过 setTreeData 更新组件状态,React 会自动重新渲染组件并展示新数据。

尤其如果部门比较多的情况下,界面可以先出来,等数据获取完毕组装好了再次渲染树形组件,这种体验就比较好了

3 保存部门信息

数据我们现在已经可以从变量中读取了,剩下就是添加的时候将新增的部门信息保存到数据源里。这里我们调用微搭的写入方法,修改如下代码

// 添加子部门逻辑const handleAddChild = () => {if (!newDepartmentName.trim()) {return Modal.warning({title: "部门名称不能为空",content: "请输入部门名称后重试。",});}// 调用数据源写入新部门$w.cloud.callDataSource({dataSourceName: "bmb", // 数据源名称methodName: "wedaCreateV2", // 假设存在 createDepartment 方法params: {data: {bmmc: newDepartmentName, // 部门名称fbm: { _id: contextMenuTargetId }, // 父部门ID},},}).then((response) => {const newId = response?.id; // 从响应中获取新节点的 IDif (!newId) {throw new Error("数据源未返回有效ID");}const newChild = {id: newId, // 使用后端返回的 IDname: newDepartmentName,parentId: contextMenuTargetId,children: [],isOpen: false,};// 更新前端树数据setTreeData((prevTreeData) =>updateTree(prevTreeData, (node) => {if (node.id === contextMenuTargetId) {node.children = [...(node.children || []), newChild];return true;}return false;}));// 关闭模态框并清空输入setAddChildModalVisible(false);setNewDepartmentName("");Modal.success({title: "添加成功",content: `子部门 "${newDepartmentName}" 已成功添加。`,});}).catch((error) => {console.error("数据源写入失败", error);Modal.error({title: "操作失败",content: "添加子部门时出现错误,请稍后重试。",});});};

需要把上边给的完整代码的handleAddChild 进行替换,这里主要是调用了微搭的创建单条的API。在创建的时候需要传递对应的数据,因为我们的父部门是关联关系,新版的关联关系是对象类型,所以我们是按照对象的结构组织了数据。

4 最终的效果

现在已经可以从数据库里读取部门的信息,并且按照树形的结构进行展示
在这里插入图片描述
点击右键的时候可以添加部门,数据库里可以看到写入的数据
在这里插入图片描述

5 总结

我们本篇介绍了如何将前后端的功能连接起来,从代码上来讲还是比较复杂的,主要需要考虑react组件加载的机制,副作用的理解,以及微搭的异步加载机制。要想理解好这些概念需要你亲自做一遍,才会有深入的体会。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/490621.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《自制编译器》--青木峰郎 -读书笔记 编译hello

在该书刚开始编译hello.cb时就遇到了问题。 本人用的是wsl&#xff0c;环境如下&#xff0c; 由于是64位&#xff0c;因此根据书中的提示&#xff0c;从git上下载了64位的cb编译器 cbc-64bit 问题一: 通过如下命令编译时,总是报错。 cbc -Wa,"--32" -Wl,"-…

Ubuntu安装Gitlab详细图文教程

1、环境准备 1.1、Ubuntu环境 Ubuntu24.04Sever版安装教程 1.2、更新系统 sudo apt update -y sudo apt-get update sudo apt-get upgrade 2、安装Nginx 2.1 安装nginx # 安装 apt install nginx -y 2.2 修改nginx配置⽂件 # 修改nginx配置 vim /etc/nginx/si…

前端0基础用Cursor完成管理系统页面 - 1

Cursor下载 下载链接: https://www.cursor.com/ Hello World! 作为完全不会前端的人&#xff0c;首先需要让AI帮我们搭建一个HelloWorld界面 确定语言框架 首先要给AI框定好前端语言和框架&#xff0c;由于AI的物料大量来自网上的开源项目&#xff0c;所以越是受欢迎的开源…

[创业之路-190]:《华为战略管理法-DSTE实战体系》-2-华为DSTE战略管理体系概要

目录 一、DSTE战略管理体系与BLM的关系 1、DSTE战略管理体系概述 2、BLM模型概述 3、DSTE与BLM的关系 二、重新认识流程 1. 流程就是业务本身&#xff0c;流程是业务过程的可视化&#xff1a; 2. 流程是业务最佳路径的经验教训总结&#xff1a; 3. 流程是战略知识资产、…

ansible自动化运维(三)jinja2模板roles角色管理

相关文章ansible自动化运维&#xff08;一&#xff09;简介及清单,模块-CSDN博客ansible自动化运维&#xff08;二&#xff09;playbook模式详解-CSDN博客ansible自动化运维&#xff08;四&#xff09;运维实战-CSDN博客 三.Ansible jinja2模板 Jinja2是Python的全功能模板引…

硬件成本5元-USB串口采集电表数据完整方案-ThingsPanel快速入门

ThingsPanel开源物联网平台支持广泛的协议&#xff0c;灵活自由&#xff0c;本文介绍ThingsPanel通过串口来采集电表数据&#xff0c;简单易行&#xff0c;成本低廉&#xff0c;适合入门者学习试验&#xff0c;也适合一些特定的应用场景做数据采集。 适用场景&#xff1a; 降低…

域名信息收集(小迪网络安全笔记~

附&#xff1a;完整笔记目录~ ps&#xff1a;本人小白&#xff0c;笔记均在个人理解基础上整理&#xff0c;若有错误欢迎指正&#xff01; 2.1 域名信息收集 引子&#xff1a;上一章介绍了服务器的信息收集。本篇则介绍在面对存在Web资产企业时&#xff0c;其域名信息该如何收…

一些浅显易懂的IP小定义

IP归属地&#xff08;也叫IP地址&#xff0c;IP属地&#xff09; 互联网协议地址&#xff0c;每个设备上的唯一的网络身份证明。用于确保网络数据能够精准传送到你的设备上。 基于IP数据云全球IP归属地解析&#xff0c;示例Python代码 curl -X POST https://route.showapi.co…

AI发展与LabVIEW程序员就业

人工智能&#xff08;AI&#xff09;技术的快速发展确实对许多行业带来了变革&#xff0c;包括自动化、数据分析、软件开发等领域。对于LabVIEW程序员来说&#xff0c;AI的崛起确实引发了一个值得关注的问题&#xff1a;AI会不会取代他们的工作&#xff0c;导致大量失业&#x…

【Git】:企业级开发和多人协作开发啊

目录 多人协作 模拟配置多人协作环境 多人同一分支开发 多人不同分支开发 远程分支删除后的问题 企业级开发模型 系统开发环境 分支设计规范 多人协作 模拟配置多人协作环境 目前&#xff0c;我们所完成的工作如下&#xff1a; 基本完成 Git 的所有本地库的相关操作&#xff…

【TypeScript】Vue: Property finally does not exist on type Promise<void>.

【TypeScript】Vue: Property finally does not exist on type Promise&#xff1c;void&#xff1e;. 问题描述 Vue: Property finally does not exist on type Promise<void>. Do you need to change your target library? Try changing the lib compiler option to…

【CSS in Depth 2 精译_079】第 13 章:渐变、阴影与混合模式概述 + 13.1:CSS 渐变效果(一)——使用多个颜色节点

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第四部分 视觉增强技术 ✔️【第 13 章 渐变、阴影与混合模式】 ✔️ 13.1 渐变 ✔️ 13.1.1 使用多个颜色节点&#xff08;一&#xff09; ✔️13.1.2 颜色插值13.1.3 径向渐变13.1.4 锥形渐变 文…

043_Tcpip Instruments in Matlab中连接和调试采用TCP/IP协议的仪器

A:师兄&#xff0c;Matlab可以做什么&#xff1f; B:除了生孩子&#xff0c;什么都会。&#xff08;这下你懂师兄的意思了吧&#xff09; A:【星星眼】哦&#xff0c;那我还是可以帮兰陵王生孩子&#xff01; B:【倒】先来一点跟Matlab无关的内容&#xff0c;现在很多仪器做得非…

Vue组件相关记录

Vue组件开发 非单文件组件 创建组件api Vue.extend({}) const student Vue.extend({template: <div>{{studentName}} - {{age}}</div>,data() {return {studentName: jjking,age: 12}}})new Vue({el: #app,//局部注册components: {student: student}})不能使用e…

EfficientNet与复合缩放理论(Compound Scaling Theory) 详解(MATLAB)

1.EfficientNet网络与模型复合缩放 1.1 EfficientNet网络简介 1.1.1 提出背景、动机与过程 EfficientNet是一种高效的卷积神经网络&#xff08;CNN&#xff09;&#xff0c;由Google的研究团队Tan等人在2019年提出。EfficientNet的设计目标是提高网络的性能&#xff0c;同时减…

Three.js案例-360° VR看房

在 360 看房功能中&#xff0c;我们需要在浏览器中创建一个类似虚拟现实的场景&#xff0c;使得用户能够查看环境的每一个角落。这一功能的实现本质上是利用 球体映射技术&#xff0c;即通过将全景图作为纹理贴图映射到一个反向的球体上&#xff0c;用户可以通过旋转视角来“环…

如何制作一款电子桌宠小狗(硬件部分)开源

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 在科技与创意的交融中&#xff0c;我开启了一段用 STM32 单片机制作电子桌宠小狗的有趣之旅。在这个项目中&#xff0c;我们将看到各种硬件组件的巧妙结合&#xff0c;共同打造出一个可爱又灵动的小宠物。 一、STM32…

期末速成C++【初识C++】

目录 1.英文单词 2.C的特点 3.C对C语言的补充 3.1命名空间和域操作符 &#x1f387;3.2控制台输入输出 3.3类型增强 3.3.1const常变量 3.3.2const与指针 3.3.3布尔类型与枚举类型 3.4默认参数 &#x1f387;3.5函数重载 &#x1f387;引用 3.6.1引用做函数参数 …

《数据结构》(408代码题)

2009 单链表&#xff08;双指针&#xff09; 分析&#xff1a;首先呢&#xff0c;给我们的数据结构是一个带有表头结点的单链表&#xff0c;也不允许我们改变链表的结构。链表的长度不是直接给出的啊&#xff0c;所以这个倒数也很棘手。那我们该如何解决这个“k”呢&#xff0c…

在 Visual Studio Code 中编译、调试和执行 Makefile 工程 llama2.c

在 Visual Studio Code 中编译、调试和执行 Makefile 工程 llama2.c 1. Installing the extension (在 Visual Studio Code 中安装插件)1.1. Extensions for Visual Studio Code1.2. C/C1.2.1. Pre-requisites 1.3. Makefile Tools 2. Configuring your project (配置项目)2.1.…