• 同时使用 Ant Design of React 中 Mention 和 Form


    使用场景,在一个列表中,点击每一行会弹出一个表单,通过修改表单数据并提交来修改这一行的数据,其中某个数据的填写需要通过Mention实现动态提示及自动补全的功能。

    具体效果为:

    遇到的问题:

    1、希望所需要的提示和自动补全的内容不同,实际场景类似于ide中函数提示(包含参数和返回值以及用法等提示)和函数补全(只补全函数名)的功能。

    Ant Design的Mention组件提供了Nav可以实现这个功能,但是实际使用中发现会报错,经查发现为Ant Design的一个bug,升级版本解决。

    2、然后遇到问题,发现suggestions使用了Nav数组之后,不能通过输入自动动态查询,具体表现为

     

    经查原因为,将生成suggestions的计算写到了引用Mention的地方:

    const suggestions = [
      {children:'张三 男 18 会计', value:'张三'},
      {children:'李四 女 21 审计', value:'李四'},
      {children:'王五 男 33 总监', value:'王五'}
    ]
    <Mention
      style={{  '100%' }}
      suggestions={ suggestions.map( (x) => <Nav {...x} />) }
    />

    解决方法,将计算过程提到外面去……

    3、点击不同数据行的时候,弹出表单数据不更新,也就是表单的 initialValue 不生效

    在 react 生命周期 componentWillReceiveProps(nextProps) 中把 Mention 的数据更新。

    需要注意的地方是 Mention 的 value 不是 string,需要在多处通过 toString 和 toContentState 进行转换。

    行吧,困扰了两天的bug好像写出来也没什么东西……QAQ怪我蠢……

    完整代码:

    import React from 'react';
    import { Table, Icon, Button, Form, Input, Modal, Mention } from 'antd';
    const FormItem = Form.Item;
    const { toString, toContentState, Nav } = Mention;
    
    const suggestions = [
      <Nav children='张三 男 18 会计' value='张三' />,
      <Nav children='李四 女 21 审计' value='李四' />,
      <Nav children='王五 男 33 总监' value='王五' />
    ]
    
    
    class EditForm extends React.Component {
      onSave = () => {
        this.props.form.validateFields((err, values) => {
          if (!err) {
            this.props.onSave({ ...values, person: toString(values.person) })
            this.props.form.resetFields()
            this.props.form.setFieldsValue({person: toContentState('')})
            console.log(toString(this.props.form.getFieldValue('person')))
          }
        });
      }
      onCancel = () => {
        this.props.onCancel()
        // 重置为初始值 initialValue 防止点击不同区域出现数据不刷新的情况(although...i dont know why...
        this.props.form.resetFields()
      }
      // 在接受 props 时调用 无论 nextProps 和 this.props 是否相等
      // 首先要在表单隐藏变为显示的时候赋值 其次 只有当前已经存在显示值的时候才调用 否则没意义 也会存在 getFiledsValue 未注册情况
      componentWillReceiveProps(nextProps) {
        if (nextProps.visible === true && this.props.visible === false && this.props.record) {
          this.props.form.setFieldsValue({person: toContentState(nextProps.record.person)})
        }
      }
      render() {
        // console.log(this.props)
        const { record, visible, onCancel  } = this.props;
        if (!record) return null;
        const { getFieldDecorator } = this.props.form;
        return (
          <Modal
            visible={visible}
            title="编辑事件"
            okText="保存"
            onCancel={this.onCancel}
            onOk={this.onSave}
          >
            <Form layout="vertical" onSubmit={this.handleSubmit}>
              <FormItem>
                {getFieldDecorator('event', {
                  rules: [{ required: true, message: '请输入事件!' }],
                  initialValue: record.event
                })(
                  <Input />
                )}
              </FormItem>
              <FormItem>
                {getFieldDecorator('person', {
                  initialValue: toContentState(record.person),
                  rules: [{ required: true, message: '请输入相关人员!' }],
                })(
                  <Mention
                    style={{  '100%' }}
                    suggestions={ suggestions }
                  />
                )}
              </FormItem>
            </Form>
          </Modal>
        );
      }
    }
    
    const WrappedEditForm = Form.create()(EditForm);
    
    
    class EventTable extends React.Component {
      state = {
        visible: false,
        record: null,
        index: 0
      }
      columns = [
        {
          title: '操作',
          key: 'action',
          render: (text, record, index) => 
            <div>
              <Button onClick={()=>{ this.setState({
                visible: true,
                record,
                index
              }) }}>编辑</Button>
            </div>,
             200
        }, 
        {
          title: '事件',
          dataIndex: 'event',
          key: 'event',
          render: (text, record, index) => 
            <div>
              <span>{text}</span>
            </div>,
             200
        },
        {
          title: '相关人员',
          dataIndex: 'person',
          key: 'person',
           200
        }
      ];
      data = [
        {
          key: '1',
          event: '早餐',
          person: '@组长',
        }, {
          key: '2',
          event: '午餐',
          person: '@组长',
        }, {
          key: '3',
          event: '晚餐',
          person: '@组长',
        }
      ];
      onCancel = () => {
        this.setState({visible: false})
      }
      onSave = (values) => {
        this.setState({visible: false})
        this.data[this.state.index].event = values.event
        this.data[this.state.index].person = values.person
      }
      render() {
        return (
          <div>
            <Table columns={this.columns} dataSource={this.data} style={{  600 }}/>
            <WrappedEditForm visible={this.state.visible} record={this.state.record} 
              onCancel={this.onCancel} onSave={this.onSave} />
          </div>
        )
      }
    }
    
    export default EventTable
  • 相关阅读:
    fescar源码解析系列(一)之启动详解
    dubbo源码解析二 invoker链
    dubbo源码解析一
    CSP-S 2021 游记
    使用SpEL记录操作日志的详细信息
    Router 重定向和别名是什么?
    vue项目做seo(prerender-spa-plugin预渲染)
    vue3.0初体验有哪些实用新功能
    uniapp弹窗踩坑
    Spring boot application.properties 配置
  • 原文地址:https://www.cnblogs.com/wenruo/p/8041083.html
Copyright © 2020-2023  润新知