项目实战之TABLE、MODAL组件的CRUD实现

       TABLE、MODAl组件的CRUD,是我项目实战的入门功能。经过这一个功能,就能够基本了解到React在项目中如何使用。其实我踩过不少的坑,我尽可能把他们记录下来,让你们可以成功地跨过去。javascript

      一.功能描述,基本的列表,可分页查询,弹窗方式的增删改。如图:java

     

  二.功能代码react

import React from 'react';
import './index.less';
import {Button, Table, Icon, Affix, Modal, Form, Input, Checkbox, Pagination,Select} from 'antd';
import {message, notification} from 'antd';
import request from '../../utils/request.js';
import moment from 'moment';

const FormItem = Form.Item;
const logger = Logger.getLogger('Cache');
const clusterData = ['select an option','man', 'ware'];

class Cache extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      visible: false,
      data: [],
      tableLoading: false,  // 表格是不是loading状态
      currentPage: 1,  // 当前第几页
      pageSize: 20,  // pageSize暂时不可修改, 固定20
      total: 0,  // 总共有多少条数据
      checkStatus: 0
    }
  }
  /**
   * 刚进入页面时触发一次查询
   */
  componentDidMount() {
    this.refresh();
  }

  /**
   * 切换分页时触发查询
   *
   * @param page
   */
  handlePageChange = (page) => {
    logger.debug('handlePageChange, page = %d', page);
    this.setState({tableLoading: true});
    const hide = message.loading('正在查询...', 0);
    const url = `...`;//具体访问地址
    const obj = {};
    obj.page = page;
    request.POST(url,obj)
      .then(resp => {
        hide();
        const result = JSON.parse(resp);
        if(result.code === 100){
          this.setState({
            currentPage: page,    //当前页
            data: result.data,    //由后台返回的记录集
            total: result.total,  //记录的总条数
            tableLoading: false,
          });
        }
      })
      .fail(error => {
        hide();
        ...//可增长失败相关处理
      })
  }

  /**
   * 按当前的查询条件从新查询一次
   */
  refresh = () => {
    this.setState({tableLoading: true});
    const hide = message.loading('正在查询...', 0);
    const url = `...`;// 拼接要请求的url地址
    const obj = {};
    obj.page = this.state.currentPage;
      request.POST(url,obj)
      .then(resp => {
        hide();
        const result = JSON.parse(resp);
        if(result.code === 100){
          this.setState({
            data: result.data,
            total: result.total,
            tableLoading: false,
          });
        }
      })
      .fail(error => {
        hide();
        ...//可增长失败的相关处理
      })
  }

  //点击doAdd操做
  handleOk = (e) => {
    const newObj = {};
    const oldObj = this.props.form.getFieldsValue();
    Object.assign(newObj, oldObj, {
      isHash: this.state.checkStatus
    })
    this.setState({
      visible: false,
    });
    if (this.state.modalInsert) {
      this.handleInsert(newObj);
    } else {
      this.handleUpdate(newObj);
    }
  }

  //选中是true值转为1,不然就是0
  handleIsChecked = (e) => {
    this.setState({
      checkStatus: e.target.checked ? 1: 0
    })
  }

  handleInsert = (obj) => {
    const url = `...`;  //添加方法的访问地址
    const hide = message.loading('正在新增...', 0);
    logger.debug('handleInsert: url = %s, obj = %o', url, obj);

    request.POST(url, obj)
      .then(resp => {
        hide();
        const result = JSON.parse(resp);
        if(result.code === 100){
          notification.success({
            message: '新增成功',
            description: '。。。',
            duration: 3,
          });
          this.refresh();
        }
      })
      .fail(error => {
        hide();
        ...//失败相关处理
      })
  }

  handleUpdate = (obj) => {
    const key = obj.id;
    const url = `...`;
    const hide = message.loading('正在更新...', 0);
    logger.debug('handleUpdate: url = %s, obj = %o', url, obj);

    request.POST(url, obj)
      .then(resp => {
        hide();
        const result = JSON.parse(resp);
        if(result.code === 100){
          notification.success({
            message: '更新成功',
            description: '...',
            duration: 3,
          });
          this.refresh();
        }
      })
      .fail(error => {
        hide();
        ...//失败时的相关处理
      })
  }

  handleDelete = (id) => {
    const url = `...`;
    const hide = message.loading('正在删除...', 0);
    logger.debug('handleDelete: url = %s', url);
    const obj = {};
    obj.id = id;
    request.POST(url, obj)
      .then(resp => {
        hide();
        const result = JSON.parse(resp);
        if(result.code === 100){
          notification.success({
            message: '删除成功',
            description: '...',
            duration: 3,
          });
          this.refresh();
        }
      })
      .fail(error => {
        hide();
        ...//失败时的相关处理
      })
  }

  //点击取消按钮的操做
  handleCancel = (e) => {
    this.setState({
      visible: false,
    });
  }

  //新增按钮操做
  onClickInsert = (e) => {
    e.preventDefault();
    this.props.form.resetFields();
    this.setState({
      visible: true,
      modalTitle: '新增缓存key',  // modal标题
      modalInsert: true,  // 当前modal是用来insert仍是update
    });
  }

  //修改按钮操做
  onClickUpdate = (record, e) => {
    e.preventDefault();
    this.props.form.resetFields();
    //数据回显
    this.props.form.setFieldsValue(record);
    this.setState({
      visible: true,
      modalTitle: '修改缓存key',  // modal标题
      modalInsert: false,   //true是insert;false是update
    });
  }
  //删除按钮操做
  onClickDelete = (id, e) => {
    e.preventDefault();
    Modal.confirm({
      title: '确认删除吗?',
      content: `当前选中的id: ${id}`,
      onOk: () => {
        this.handleDelete(id);
      },
    });
  }

  render() {
    let self = this;
    const clusterOptions = clusterData.map(cluster => <Option key={cluster}>{cluster}</Option>);
    const formItemLayout = {
      labelCol: {
        xs: {span: 24},
        sm: {span: 6},
      },
      wrapperCol: {
        xs: {span: 24},
        sm: {span: 14},
      },
    };
    const tailFormItemLayout = {
      wrapperCol: {
        xs: {
          span: 24,
          offset: 0,
        },
        sm: {
          span: 14,
          offset: 6,
        },
      },
    };
    const {getFieldDecorator} = this.props.form;
    const columns = [{
      title: 'ID',
      dataIndex: 'id',
      key: 'id',
    }, {
      title: 'key值',
      dataIndex: 'cacheKey',
      key: 'cacheKey',
    }, {
      title: 'key值含义描述',
      dataIndex: 'keyDesc',
      key: 'keyDesc',
    }, {
      title: '所属redis集群',
      dataIndex: 'belongCluster',
      key: 'belongCluster',
    }, {
      title: '是否hash存储',
      dataIndex: 'isHash',
      key: 'isHash',
      render: (text, record) => (
        record.isHash == 1 ? '是':'否'
      ),
    }, {
      title: '建立时间',
      dataIndex: 'created',
      key: 'created',
      render: (text, record) => (
      moment(text).format('YYYY-MM-DD')
      ),
    }, {
      title: '修改时间',
      dataIndex: 'modified',
      key: 'modified',
      render: (text, record) => (
        moment(text).format('YYYY-MM-DD')
      ),
    }, {
      title: '操做',
      key: 'action',
      render: (text, record) => (
        <span>
      <a href="javascript:return false;" onClick={self.onClickUpdate.bind(this, record)}>修改</a>
      <span className="ant-divider"/>
      <a href="javascript:return false;" onClick={self.onClickDelete.bind(this, record.id)}>删除</a>
    </span>
      ),
    }];

    return (
      <div>
        <div>
          <Affix offsetTop={8}>
            <Button type="primary" onClick={this.onClickInsert}>
              <Icon type="plus-circle-o"/> 新增
            </Button>
          </Affix>
          <Modal title={this.state.modalTitle} visible={this.state.visible}
                 onOk={this.handleOk} onCancel={this.handleCancel}>
            <Form layout="horizontal" >
              <FormItem {...formItemLayout} label="缓存Key">
                {getFieldDecorator('cacheKey', {
                  rules: [{ required: true, message: 'Please input cacheKey!' }],
                })(
                  <Input type="text"  />
                )}
              </FormItem>
              <FormItem  {...formItemLayout} label="key值描述">
                {getFieldDecorator('keyDesc', {
                  rules: [{ required: true, message: 'Please input keyDesc!' }],
                })(
                  <Input type="textarea"  autosize={{minRows: 2, maxRows: 6}}/>
                )}
              </FormItem>
              <FormItem {...formItemLayout} label="所属redis集群">
                {getFieldDecorator('belongCluster', {
                  initialValue: clusterData[0],
                  rules: [{ required: true, message: 'Please select keyDesc!' }],
                })(
                  <Select>
                    {clusterOptions}
                  </Select>
                )}
              </FormItem>
              <FormItem {...tailFormItemLayout} style={{marginBottom: 8}}>
                {getFieldDecorator('isHash', {
                  valuePropName: 'checked'
                })(
                  <Checkbox onChange={self.handleIsChecked.bind(this)}>是否hash存储</Checkbox>
                  )}
              </FormItem>
              <FormItem>
                {getFieldDecorator('id', {
                })(
                  <input type="hidden"/>
                )}
              </FormItem>
            </Form>
          </Modal>
        </div>
        <Table columns={columns} dataSource={this.state.data} pagination={false}/>
        <Pagination defaultCurrent={1} total={this.state.total} current={this.state.currentPage}
                    pageSize={this.state.pageSize} onChange={self.handlePageChange.bind(this)}/>
      </div>
    );
  }
}
Cache = Form.create()(Cache);
export default Cache;

  三. 坑点提示redis

  1.return();方法里面的内容只容许有一个<div></div>,其余的组件可放入div里面。缓存

    2.return();方法里面的组件,Table、Modal、Pagination组件使用以前,须要如今代码最前面import.可参考代码antd

    3.使用Form需Cache = Form.create()(Cache); Cache是class的名称;FormItem的使用,需定义变量:const FormItem = Form.Item;app

    4.在anted 2以上推荐使用getFieldDecorator。使用getFieldDecorator,经过方法this.props.form.getFieldsValue()能够获取到表单中各个字段的值。注意在render()方法里,在return()方法以前添加const {getFieldDecorator} = this.props.form; 具体使用可见代码less

    5.具体使用ant desgin的组件好比Form的不少属性能够去官网上看说明。ide

相关文章
相关标签/搜索