項目實戰之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

相關文章
相關標籤/搜索