从零实现一套低代码(保姆级教程)【后端服务】 --- 【10】实现Form组件的数据录入

发布于:2024-05-09 ⋅ 阅读:(23) ⋅ 点赞:(0)

摘要

在上一篇中,我们实现了数据的持久化展示。可以通过表格将数据库中的数据展示出来。有了展示,那么就要有可以录入的组件。而我们之前实现的Form组件,就可以完成数据的录入。

现在要做的就是,怎么修改Form组件,让他能够将数据存储到数据库中。 我们肯定希望的是,在Form组件下有一些Input输入框,然后点击一个保存按钮,就可以将数据保存在数据库里面。

现在我们来开始实现这一个需求问题。

1.绑定实体

我们实现的Form表单组件,一定是要关联一个实体的。意思就是,我们需要知道往数据库里的哪张表存数据。而这个属性,在上一篇我们正好为了表格实现了。就是选择实体的这个属性。

我们只需要来到Form组件的属性配置里面:

import { ComAttribute } from "../attributeMap"

const formAttribute: ComAttribute[] = [
  {
    label: '设置标题',
    value: 'caption',
    type: 'input'
  },
  {
    label: '选择实体',
    value: 'entityCode',
    type: 'modal',
    modalType: 'EntitySelect'
  },

增加一个选择实体的属性,这样就可以把Form组件和数据库表关联起来了。 而且Form组件会有两个属性entityCode和schemaList。

image.png

2.根据schema生成输入框

现在我们有了数据库表的schema结构之后,我们希望给Form组件生成一些Input组件。每一个Input组件对应一个实体的字段。

这里我们封装一个生成节点的方法,很简单,只需要返回一个对象即可。 在Utils下的nodeUtils文件中:

let num = 0;

const createCom = (props: any) => {
  const { comType, caption = `${comType}${++num}` } = props;
  let comId = `comId_${Date.now()}${++num}`;
  return {
    comId,
    comType,
    caption,
    ...props
  }
}

现在我们回到Form组件里,从props里面拿到schemaList和entityCode,遍历schemaList,给Form组件生成对应的childList。

  useEffect(() => {
    if(entityCode && schemaList?.length > 0) {
      const formNode = getComById(comId, comList);
      formNode.childList = []
      const inputList = schemaList.map((item: string) => {
        return createCom({comType: 'Input', caption: item, label: item})
      })
      formNode.childList.push(...inputList)
      Store.dispatch({type: 'changeComList', value: JSON.parse(JSON.stringify(comList))})
    }
  }, [])

这里注意下,我们希望绑定实体的Form表单,只有和实体相关的Input,不需要其他的Input组件。所以一开始我会给childList置空。

完成之后我们就可以看到和实体字段对应的Input组件了。

image.png

3. 获取输入框的值

现在我们有了输入框,我们需要能拿到在输入框中输入的内容。所以现在我们要给Input组件增加一个属性,表示输入框的内容。

而这个属性,不需要体现在右侧的属性面板上,因为我们更改输入框的值,是通过在输入框中输入来实现的。所以我们只需要修改一下Input组件:

  const comList = JSON.parse(JSON.stringify(Store.getState().comList))

  const changeValue = (e: any) => {
    const inputNode = getComById(comId, comList);
    inputNode.value = e.target.value;
    Store.dispatch({type: 'changeComList', value: comList})
  }
  }
 

我们给Input组件增加一个onChange事件,更新组件的value值。

现在我们来一个Button组件在最下面,把所有Input框的内容打印出来,我们实现一下它的onClick事件。

  const submit = () => {
    const childList = formNode.childList || [];
    const data: any = {};
    childList.forEach((element: any) => {
      if(element.label) {
        data[element.label] = element.value
      }
    });
    console.log(data);
    
  }

实现完,点击后我们可以看到:

image.png

这里要注意的是,这个保存按钮,必须要在选择实体后才出现,不然你能保存到哪里呢?

4.存储数据

现在我们拿到了这些数据,只需要后续保存到数据库里面即可。我们之前实现了保存数据的借口,需要entityCode和entityParam这两个字段。现在我们都有了,直接进行存储!

修改我们的submit方法:

  const submit = () => {
    const childList = formNode.childList || [];
    const data: any = {};
    childList.forEach((element: any) => {
      if(element.label) {
        data[element.label] = element.value
      }
    });

    if(entityCode) {
      axios.post("http://localhost:4000/entity/addEntityData", {
        entityCode,
        entityParam: {...data}
      })
      .then(res => {
        if(res.data.code === 200) {
          message.success('添加成功')
        }else {
          message.error('添加失败')
        }
      })
    }
  }

这部分代码提交在github上

commit: fix: 第二十节:修改Form组件,实现数据存储

博主补充

到此为止,我们的后端服务基本就算是差不多了。我们做到了数据存储和展示。当然这里的数据不只是冰冷的文字,我们也完成了图片的存储和展示。分别用到了Image组件和Upload组件。

在上面,我们有一个保存的事件逻辑。这种功能应该在运行时里面实现,但是为了展示数据的存储,所以在设计态给暴露出来了。后面我们会继续完成运行时的部分。

所以到这里,第二部分,后端服务已经完成了!