摘要
经过前面几章的内容,我们的后端服务已经支持了对页面的管理,对图片的管理,并且也支持了在XinBuilder中如何去使用它们。其实到目前为止,我们的XinBuilderServer服务,已经具备了基本的功能了。
可能是因为我是前端开发的原因,所以我在做这个项目重点一直是放在前端的功能实现的。后端代码比较少。
话说回来,这一篇继续回归到XinBuilder的项目里,再上一篇中,我们实现了和实体相关的后端内容,也就是我们有了持久化的数据存储。但是有了数据之后,我们如何能够在低代码项目里面使用?
对于数据的使用无非就是数据的处理以及数据的展示,在数据展示上,我们有很多种方式,比较常见的有表格,列表等等。
本篇主要通过Table组件来串通数据在XinBuilder中如何展示。
1.创建一张Student表
前期的准备工作,我们就在平台下创建一张Student表。
创建好后,我们来到swagger中,给这张表增加几条数据。
这里可以多加一些数据,方便后续的展示。
有了数据之后,我们希望的是,在XinBuilder中实现一个Table组件,可以去展示这些数据。或者去展示某张表的部分数据。
所以Table组件是一定需要一个属性,去选择对应的实体以及字段。
2.创建Table组件,实现选择实体的功能
Table组件我们放在数据展示分组里面,之前写过很多组件的创建。至于创建组件的过程,这里就不去贴代码了。
我们要实现的是给Table组件能够选择实体的功能。
所以在tableAttribute中,我们需要一个弹窗类型的属性。
javascript
{
label: '选择实体',
value: 'entityCode',
type: 'modal',
modalType: 'EntitySelect'
},
同时,在modal下新建一个EntitySelect的文件夹。用来去选择对应的实体,和实体下面的字段。
我们要实现出一个可以选择实体,以及实体下字段的弹窗。
上面的Select选择器用来选择对应的实体,然后再通过Switch去选择该实体下的字段。 所以对于表格组件就需要两个属性。
entityCode:实体编码 schemaList:需要展示的字段
这里我们贴一下弹窗的代码:
javascript
import { useEffect, useState } from 'react';
import { Modal, Select, Switch, message } from 'antd';
import { getComById } from '../../../utils/nodeUtils'
import Store from '../../../store/index'
import axios from 'axios';
export interface Entity {
entityCode: string,
entityName: string,
entitySchema: EntitySchema
}
interface EntitySchema {
[key: string]: string
}
const EntitySelect: React.FunctionComponent = (props: any) => {
const { openModal, setOpenModal, valueKey } = props;
const comList = JSON.parse(JSON.stringify(Store.getState().comList))
const selectCom = Store.getState().selectCom
const selectNode = getComById(selectCom, comList)
const [nodeSchemaList, setNodeSchemaList] = useState([...(selectNode.schemaList || [])])
const [entityList, setEntityList] = useState<Entity []>([])
const [selectEntity, setSelectEntity] = useState(selectNode.entityCode || '')
useEffect(() => {
axios.post("http://localhost:4000/entity/getEntityList")
.then(res => {
if(res.data.data) {
setEntityList(res.data.data)
}else {
message.error("请求实体列表失败")
}
})
}, [])
const handleCancel = () => {
setOpenModal(false)
setSelectEntity(selectNode.entityCode || '')
setNodeSchemaList([...(selectNode.schemaList || [])])
}
const handleOk = () => {
if(selectNode) {
selectNode[valueKey as keyof typeof selectNode] = selectEntity;
selectNode.schemaList = nodeSchemaList;
}
Store.dispatch({type: 'changeComList', value:comList})
setOpenModal(false)
setSelectEntity(selectNode.entityCode || '')
setNodeSchemaList([...(selectNode.schemaList || [])])
}
const getOptions = () => {
return entityList.map((item: Entity) => {
return {
value: item.entityCode,
label: item.entityCode
}
})
}
const changeEntity = (value: string) => {
setSelectEntity(value)
setNodeSchemaList([])
}
const changeSwitch = (schemaCode: string) => {
return (value: boolean) => {
if(value && !nodeSchemaList.includes(schemaCode)) {
nodeSchemaList.push(schemaCode)
}else if(!value && nodeSchemaList.includes(schemaCode)) {
const index = nodeSchemaList.indexOf(schemaCode);
nodeSchemaList.splice(index,1)
}
setNodeSchemaList([...nodeSchemaList])
}
}
const getSchemaList = () => {
const entity = entityList.find((item: Entity) => item.entityCode === selectEntity);
const schemaList = Object.keys(entity?.entitySchema || {}) || [];
return <div style={{display:'flex', width:400, justifyContent:'flex-start',flexWrap:'wrap'}}>
{
schemaList.map(item => {
return <div style={{width:'100px'}}>
<p>{item}</p>
<Switch onChange={changeSwitch(item)} value={nodeSchemaList.includes(item)}></Switch>
</div>
})
}
</div>
}
return <Modal closable={false} open={openModal} onOk={handleOk} onCancel={handleCancel}>
<div style={{width:250, display:'flex',justifyContent:'space-between'}}>
<div style={{marginTop:'5px', fontWeight:1000}}>选择实体:</div>
<Select onChange={changeEntity} value={selectEntity} style={{width: 150}} options={getOptions()}></Select>
</div>
<div>
{
getSchemaList()
}
</div>
</Modal>;
};
export default EntitySelect;
Ok,有了这个弹窗之后,我们就可以给表格组件赋予这两个属性了。
3.实现表格的数据展示
当表格组件有了这两个属性之后,我们就可以在表格内部通过ajax请求到对应的数据。 赋给表格的columns属性和datasource属性。
javascript
import { useState, useEffect } from 'react';
import { Table as AntTable, message } from 'antd';
import axios from 'axios';
const Table: React.FunctionComponent = (props: any) => {
const { entityCode, schemaList, size, bordered, showHeader = true, pagination = false, comStyle } = props;
const [entityData, setEntityData] = useState([])
useEffect(() => {
axios.post("http://localhost:4000/entity/getEntityData", {entityCode})
.then(res => {
if(res.data.data) {
setEntityData(res.data.data)
}
})
}, [entityCode])
const getColumns = () => {
return schemaList.map((item: any) => {
return {
title: item,
dataIndex: item,
key: item
}
})
}
const getData = () => {
return entityData.map((item: any) => {
return {
key: item._id,
...item
}
})
}
return <AntTable
dataSource={getData()}
columns={getColumns()}
size={size}
pagination={pagination}
bordered={bordered}
showHeader={showHeader}
style={{...comStyle}}
/>;
};
export default Table;
4.补充表格的其他属性
最后我们在给表格补充一下其他属性和样式。 就可以通过关联对应的实体,确定表格的columns和data。从而正常展示数据库中的数据了。
这部分代码提交在github上
github.com/TeacherXin/...
commit: fix: 第十九节:增加Table组件