同時使用 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={{ width: '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={{ width: '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>,
        width: 200
    }, 
    {
      title: '事件',
      dataIndex: 'event',
      key: 'event',
      render: (text, record, index) => 
        <div>
          <span>{text}</span>
        </div>,
        width: 200
    },
    {
      title: '相關人員',
      dataIndex: 'person',
      key: 'person',
      width: 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={{ width: 600 }}/>
        <WrappedEditForm visible={this.state.visible} record={this.state.record} 
          onCancel={this.onCancel} onSave={this.onSave} />
      </div>
    )
  }
}

export default EventTable

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM