Flex 学习之路之九 用户接口user interface includeInLayout 和visible区别

本文介绍了一个使用Adobe Flex的Spark组件集实现的简单应用案例。通过两个按钮切换面板的可见性和布局包含状态,演示了如何利用visible属性和includeInLayout属性控制UI元素的显示与隐藏效果。
<?xml version="1.0"?>
<!-- components\HiddenBoxLayout.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   height="500">
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
	<s:SkinnableContainer>
		<s:layout>
			<s:VerticalLayout/>
		</s:layout>
		<s:Panel id="p1"
				 title="Panel 1"/>
		<s:Panel id="p2"
				 title="Panel 2"/>
		<s:Panel id="p3"
				 title="Panel 3"/>
	</s:SkinnableContainer>
	<s:SkinnableContainer>
		<s:layout>
			<s:HorizontalLayout/>
		</s:layout>
		<s:Button label="Toggle Panel 2 Visible"
				  click="{p2.visible=!p2.visible;}"/>
		<s:Button label="Toggle Panel 2 in Layout"
				  click="{p2.includeInLayout=!p2.includeInLayout;}"/>
	</s:SkinnableContainer>
</s:Application>

visible 表示控件消失了,位置还在,includeInLayout表示控件的位置消失了,这个位置会被其他控件所占用

要实现用户输入搜索条件后从后端查询的功能,你需要修改 `ProTable` 的 `request` 属性,使其能够接收搜索参数并传递给后端 API。以下是修改后的代码: ### 修改后的代码 ```tsx import React, { useState, useRef, useEffect } from 'react'; import { ProTable } from '@ant-design/pro-components'; import { Button, Menu, Modal, Form, Input, message } from 'antd'; import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons'; import { request } from 'umi'; interface DomainItem { id: string; areaName: string; } interface SystemItem { id: string; objName: string; objDesc: string; areaId: string; createUser: string; } const DomainBussinessObjPage: React.FC = () => { const [form] = Form.useForm(); const [domains, setDomains] = useState<DomainItem[]>([]); const [currentDomain, setCurrentDomain] = useState<string>(''); const [obj, setObj] = useState<SystemItem[]>([]); const [modalVisible, setModalVisible] = useState(false); const [modalType, setModalType] = useState<'add' | 'edit'>('add'); const [currentRecord, setCurrentRecord] = useState<SystemItem | null>(null); const actionRef = useRef(); useEffect(() => { // 获取领域数据 request('/ds/dsareainfo/list').then((res) => { setDomains(res.data); if (res.data.length > 0) { setCurrentDomain(res.data[0].id); } }); }, []); const columns = [ { title: '业务对象ID', dataIndex: 'id', key: 'id' }, { title: '对象名称', dataIndex: 'objName', key: 'objName' }, { title: '对象描述', dataIndex: 'objDesc', key: 'objDesc' }, { title: '创建人', dataIndex: 'createUser', key: 'createUser' }, { title: '操作', valueType: 'option', render: (_: any, record: SystemItem) => [ <a key="edit" onClick={() => handleEdit(record)}> <EditOutlined /> 修改 </a>, <a key="delete" onClick={() => handleDelete(record.id)}> <DeleteOutlined /> 删除 </a>, ], }, ]; const handleDomainChange = (key: string) => { setCurrentDomain(key); }; const handleAdd = () => { setModalType('add'); setModalVisible(true); form.setFieldsValue({ areaId: currentDomain }); form.resetFields(); }; const handleEdit = (record: SystemItem) => { setModalType('edit'); setCurrentRecord(record); form.setFieldsValue(record); setModalVisible(true); }; const handleDelete = (id: string) => { Modal.confirm({ title: '确认删除', content: '确定删除该业务对象吗?', onOk: () => { request('/ds/dsobjinfo/delete', { method: 'POST', data: { id }, }).then(() => { message.success('删除成功'); setObj(obj.filter((item) => item.id !== id)); }); }, }); }; const handleSubmit = () => { form.validateFields().then((values) => { const apiUrl = modalType === 'add' ? '/ds/dsobjinfo/save' : '/ds/dsobjinfo/update'; const params = modalType === 'add' ? { ...values, areaId: currentDomain } : { ...values, id: currentRecord?.id }; try { request(apiUrl, { method: 'POST', data: params, }).then((res) => { message.success(modalType === 'add' ? '新增成功' : '修改成功'); setModalVisible(false); // 刷新列表 if (currentDomain) { request('/ds/dsobjinfo/byareaid', { method: 'POST', data: { areaId: currentDomain, }, }).then((res) => { setObj(res.data); }); } }); } catch (error) { // @ts-ignore if (error.name === 'BizError') { // @ts-ignore message.error(error.message); } } }); }; return ( <div style={{ display: 'flex', height: '100%' }}> <div style={{ width: 200, background: '#fff' }}> <Menu mode="inline" selectedKeys={[currentDomain]} onClick={({ key }) => handleDomainChange(key)} > {domains.map((domain) => ( <Menu.Item key={domain.id}>{domain.areaName}</Menu.Item> ))} </Menu> </div> <div style={{ flex: 1, padding: '8px' }}> <ProTable<SystemItem> columns={columns} rowKey="id" pagination={{ pageSize: 10 }} search={{ labelWidth: 'auto', defaultCollapsed: false, }} toolBarRender={() => [ <Button key="add" type="primary" onClick={handleAdd}> <PlusOutlined /> 新增业务对象 </Button>, ]} actionRef={actionRef} request={async (params = {}) => { if (!currentDomain) { return { data: [], success: true, total: 0, }; } // 将搜索参数当前领域ID一起传递给后端 const searchParams = { ...params, areaId: currentDomain, }; try { const response = await request('/ds/dsobjinfo/byareaid', { method: 'POST', data: searchParams, }); return { data: response.data, success: true, total: response.data.length, }; } catch (error) { message.error('获取数据失败'); return { data: [], success: false, total: 0, }; } }} /> </div> <Modal title={modalType === 'add' ? '新增业务对象' : '修改业务对象'} visible={modalVisible} onOk={handleSubmit} onCancel={() => setModalVisible(false)} > <Form form={form} layout="vertical"> <Form.Item name="objName" label="业务对象名称" rules={[{ required: true, message: '请输入对象名称' }]} > <Input placeholder="请输入对象名称" /> </Form.Item> <Form.Item name="objDesc" label="对象描述" rules={[ { required: true, message: '请输入对象描述' }, { max: 30, message: '对象描述不能超过30个汉字' }, ]} > <Input.TextArea autoSize={{ minRows: 1, maxRows: 3 }} /> </Form.Item> </Form> </Modal> </div> ); }; export default DomainBussinessObjPage; ``` ### 关键修改点 1. **`request` 属性**: - 在 `ProTable` 中添加了 `request` 属性,用于处理分页、排序搜索。 - 将搜索参数(`params`)当前领域 ID(`currentDomain`)一起传递给后端 API。 2. **后端 API 调用**: - 调用 `/ds/dsobjinfo/byareaid` 接口时,传递 `searchParams`,其中包含搜索条件 `areaId`。 - 后端需要根据这些参数过滤数据并返回结果。 3. **错误处理**: - 添加了 `try-catch` 块,用于捕获请求错误并显示提示信息。 ### 后端 API 示例 后端 API 需要能够接收搜索参数并返回过滤后的数据。以下是一个可能的实现(以 Node.js 为例): ```javascript // 假设使用 Express.js app.post('/ds/dsobjinfo/byareaid', (req, res) => { const { areaId, objName, createUser, current = 1, pageSize = 10 } = req.body; // 模拟数据库查询 let data = [ // 你的数据 ]; // 根据 areaId 过滤 if (areaId) { data = data.filter((item) => item.areaId === areaId); } // 根据 objName 过滤 if (objName) { data = data.filter((item) => item.objName.toLowerCase().includes(objName.toLowerCase()), ); } // 根据 createUser 过滤 if (createUser) { data = data.filter((item) => item.createUser.toLowerCase().includes(createUser.toLowerCase()), ); } // 分页 const start = (current - 1) * pageSize; const end = start + pageSize; const result = data.slice(start, end); res.json({ data: result, total: data.length, success: true, }); }); ``` ### 总结 - 用户输入搜索条件后,`ProTable` 会自动将搜索参数传递给 `request` 方法。 - 在 `request` 方法中,将搜索参数 `currentDomain` 一起传递给后端 API。 - 后端 API 根据参数过滤数据并返回结果。 - `ProTable` 根据返回的数据渲染表格。 这样,用户就可以通过搜索框输入条件,从后端查询并过滤数据了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

computerclass

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值