网站开发中,仅仅是简单展示一下数据还远远不够,我们还会需要对数据进行更新的操作。
本小节中,我们会在页面中添加一个按钮。点击后弹出对话框,允许用户输入一条新的数据并进行更新。
引入相关依赖
我们将本次需要的组件引入进来。
import { Table, Modal, Button, Form, Input } from 'antd';const FormItem = Form.Item;
对话框
我们在页面中插入新建按钮和对话框组件。
<div><Table ... /><Button>新建</Button><Modal title="新建记录">...</Modal></div>
其中,对于 Modal 组件,我们可以通过 visible 属性来控制是否显示。
因此,我们需要将其在 state 中进行管理。
class List extends React.Component {state = {visible: false,};// ...}
按钮事件
让我们为按钮添加相应事件,使其可以改变 state 中 visible 的值。
class List extends React.Component {showModal = () => {this.setState({ visible: true });};// ...}
<Button onClick={this.showModal}>新建</Button>
设置好后,我们页面中点击按钮便会弹出对话框了。
表单
antd 提供了一套非常强大的表单组件,大部分情况下只需要简单的几步配置便可以实现验证功能。首先,我们需要将页面与表单进行关联:
export default connect(mapStateToProps)(Form.create()(List));
其中,最主要的代码是:
Form.create()(List)
这段代码的作用是创建一个高阶组件,为页面组件 List 提供表单所需要的内容(this.props.form)。
现在,我们来让对话框关联 visible 并且添加上表单支持:
render() {const { visible } = this.state;const { form: { getFieldDecorator } } = this.props;// ...return (<div>{/* ... */}<Modaltitle="新建记录"visible={visible}><Form><FormItem label="名称">{getFieldDecorator('name', {rules: [{ required: true }],})(<Input />)}</FormItem><FormItem label="描述">{getFieldDecorator('desc')(<Input />)}</FormItem><FormItem label="链接">{getFieldDecorator('url', {rules: [{ type: 'url' }],})(<Input />)}</FormItem></Form></Modal></div>);}}
我们可以看到表单组件是通过 Form 与 Form.Item (我们之前定义了 FormItem = Form.item) 配合使用,其中每一个 Form.Item 都是一个表单域。而 getFieldDecorator 是用于将包裹的组件与表单进行双向绑定使用。
此外,我们还可以设置改表单域是否是必填项(required: true)或者是否需要类型检查(type: url)。更多的配置可以查询官方文档。
然后,我们添加表单处理逻辑。添加确认和取消方法。
撤销操作
重置 visible 属性为 false 以关闭对话框。
handleCancel = () => {this.setState({visible: false,});}
确定操作
我们通过 validateFields 方法验证表单是否完成填写,通过便提交添加操作。
handleOk = () => {const { dispatch, form: { validateFields } } = this.props;validateFields((err, values) => {if (!err) {dispatch({type: 'cards/addOne',payload: values,});// 重置 `visible` 属性为 false 以关闭对话框this.setState({ visible: false });}});}
其中, dispatch 的 'cards/addOne' 请参考我们提供的对应样例中 src/model/cards 、 src/service/cards 和 mock/cards 的代码。该内容已经在第三章中讲解因而不再重复。
最后,我们为 Modal 添加事件处理:
<Modaltitle="新建记录"visible={visible}onOk={this.handleOk}onCancel={this.handleCancel}>...</Modal>
自定义控件
在 antd 中,我们提供了诸如 Input, Select 之类的用于接收用户输入的组件。但是如果这些不满足你的需要时该怎么办呢?比如你如果需要一个富文本输入框,又或者是一个复杂的多行内容输入的表格。我们怎么可以添加这些复杂的组件,让它们可以和 antd 的 Form 组件一起使用呢?
其实很简单,在上面我们介绍了 getFieldDecorator 这个方法,它执行后会返回一个函数,那个函数接收一个参数,那个参数就是一个输入组件。比如在上面的例子中它可能是 <Input /> 也有可能是 <Select />。但是它并没有被局限在 antd 支持的组件内,你完全可以传入你自己的一个组件,比如下面的示例:
<FormItem label="自定义输入">{getFieldDecorator('custom', {rules: [{ required: true }],})(<YourInput />)}</FormItem>
其中,只要 YourInput 这个组件满足如下三个条件即可:
- 提供受控属性
value或其它与valuePropName的值同名的属性。 - 提供
onChange事件或trigger的值同名的事件。 - 不能是函数式组件。
具体的可运行的例子你可以参考 Ant Design 官网的例子。
所以,如果你需要在表单中添加一个富文本组件,那么你可以在 Ant Design 官网推荐的社区精选组件中找到合适你项目的富文本编辑器组件。然后你可以自定义一个组件,该组件应该封装你找到的编辑器子组件并满足上面说的三个条件,这样你就可以在你的表单中使用它了。
思考
洋洋洒洒我们写了这么多的代码,是时候思考一下其他问题了。
目前的代码能够实现功能,但是这是最好的实现吗?
函数名和变量是否可以再改改?
是否可以把一部分代码抽离出来做成独立的模块呢?
现在页面样式布局是否还能再进行一些调整呢?
等等……
这就交给各位独立思考啦。
