react+ANTD如何反向(setState)更新table组件的dataSource?

#1

table组件有个dataSource,用来渲染table内容的,像这样:

<Table dataSource={this.state.checked} columns={columns} pagination={false}/>

我需要做的功能是如图这样:

每行都是由dataSource渲染出来的,当某个input有变化(onChange)时会将会反向更新dataSource,更新后我再获取这个dataSource是不是就可以直接得到所有行,且拥有input的value?若此办法行不通,那是不是要定位到每一个input?

请教前辈们,每个input框里他填写或更改后,如何定位到是哪一行哪一列?如何定位后得到该值?
每一行合计与每一列的合计是否与获取该值的功能写在一起?用同一个监听函数呢?

注:
1、表格里的每一行都是由一组checkbox勾选而增加出来的,也就是说行数、行内容、行左标题都不一样且不确定
2、列数确定,且固定


最后贴上代码,有些杂乱,抱歉:

import React from 'react'; //引入react
import {connect} from 'dva'; //从dva引入connect
import style from './fill.less' //引入样式文件
import {Form, Button, Row, Tabs, Checkbox, Table, InputNumber} from 'antd';
import Cookie from 'js-cookie';

const FormItem = Form.Item; //表单组
const TabPane = Tabs.TabPane; //标签组
const CheckboxGroup = Checkbox.Group; //多选组
//const {Column, ColumnGroup} = Table; //表格组

let Child = React.createClass({
  render: function () {
    return (
      <InputNumber min={0} max={24} step={0.5} onChange={this.props.onInput}/>
    )
  }
});

//初始化当前页面总组件OnePoint
class Fill extends React.Component {

  // 初始化状态
  constructor() {
    super();
    this.state = {
      formLayout: 'inline', //声明表单为行内布局样式
      dataTable: [],
      count: 0,
      checked: [],
      saveData: [],
      hang: [],
      email:''
    };
  };


  //保存的信息
  onSaveSubmit = () => {
    const {dispatch} = this.props;
    const {saveData} = this.state;
    dispatch({
      type: 'timeManagement/fillSaveTime',
      saveData
    });
  };


  onInput = (event) => {
    //this.state.checked.map(item =>(console.log(item.Sunday.props.value)));
    this.setState({
      email: event
    });

  };

  //渲染组件
  render() {

    const {formLayout} = this.state; //获取初始化时定义的表单布局样式
    const {dataTable} = this.state; //获取表格行
    const {checked} = this.state; //获取选中项
    //const {saveData} = this.state; //获取保存数据

    //防止key缺失警告
    dataTable.map((i, index) => {
      i.key = index;
    });

    //获取创建时间
    let d = new Date();
    let str = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate();

    //设置表单组标题和内容占比
    const formItemLayout = formLayout === 'horizontal' ? {
      labelCol: {span: 4},
      wrapperCol: {span: 14},
    } : null;
    const buttonItemLayout = formLayout === 'horizontal' ? {
      wrapperCol: {span: 14, offset: 4},
    } : null;


    //模拟多选数据
    const {projectList, activityType, currentWeek} = this.props;

    //遍历活动类型,并将其写成checBkox选择项
    let options = activityType.map(item => ({
      key: item.activity_code,
      label: item.activity_name,
      value: projectList[0].proj_code + '-' + item.activity_code,
      name: projectList[0].proj_code
    }));


    //遍历活动类型,并将其写成table的tr
    let dataRow;
    dataRow = activityType.map(item => ({
      key: projectList[0].proj_code + '-' + item.activity_code,
      value: item.activity_name,
      Monday: <Child name="input" onInput={this.onInput.bind(this)}/>,
      Tuesday: <Child name="input" onInput={this.onInput.bind(this)}/>,
      Wednesday: <Child name="input" onInput={this.onInput.bind(this)}/>,
      Thursday: <Child name="input" onInput={this.onInput.bind(this)}/>,
      Friday: <Child name="input" onInput={this.onInput.bind(this)}/>,
      Saturday: <Child name="input" onInput={this.onInput.bind(this)}/>,
      Sunday: <Child name="input" onInput={this.onInput.bind(this)}/>,
      typeTot: '合计',
    }));


    //获取勾选的活动类型,增加tr行
    function onChange(checkedValues) {
      let filter = [];
      filter = dataRow.filter(opt =>
        checkedValues.some(val => val === opt.key),
      );

      let fillSaveTimeData = [];
      fillSaveTimeData = checked.map(function (item) {
        let data = {
          arg_proj_code: projectList[0].proj_code,
          arg_proj_name: projectList[0].proj_name,
          staff_id: localStorage.staffid,
          login_name: localStorage.fullName,
          begin_time: currentWeek.begintime,
          end_time: currentWeek.endtime,
          dept_id: Cookie.get('dept_id'),
          activity_id: item.key.split('-')[1],
          mon: item.Monday.props.value,
          tues: item.Tuesday.props.value,
          wed: item.Wednesday.props.value,
          thur: item.Thursday.props.value,
          fri: item.Friday.props.value,
          sat: item.Saturday.props.value,
          sun: item.Sunday.props.value,
          approved_status: 0, //0保存,1提交,2审核通过,3退回,4补录工时提交(项目成员),5补录工时提交(项目经理),6补录工时保存(项目成员) 7 补录工时退回,8 历史
          row_type: 0, //记录类型,0.正常填写工时 1.补录工时,2.外包填写的工时 3.自动填加的工时
          create_time: str,
        };
        return {
          opt: "insert",
          data: data
        } //return END
      });

      this.setState({
        checked: filter,
        saveData: fillSaveTimeData
      });
    }


    //表头
    const columns = [
      {
        title: "",
        dataIndex: "value",
        key: "value"
      },
      {
        title: "星期一",
        dataIndex: "Monday",
        key: "Monday"
      }, {
        title: "星期二",
        dataIndex: "Tuesday",
        key: "Tuesday"
      }, {
        title: "星期三",
        dataIndex: "Wednesday",
        key: "Wednesday"
      }, {
        title: "星期四",
        dataIndex: "Thursday",
        key: "Thursday"
      }, {
        title: "星期五",
        dataIndex: "Friday",
        key: "Friday"
      }, {
        title: "星期六",
        dataIndex: "Saturday",
        key: "Saturday"
      }, {
        title: "星期日",
        dataIndex: "Sunday",
        key: "Sunday"
      }, {
        title: "活动类型合计",
        dataIndex: "typeTot",
        key: "typeTot"
      },

    ];

    // 遍历项目个数
    let pane = []; //定义标签页
    let proj_code; //定义得到的项目编号
    for (let i = 0; i < projectList.length; i++) {
      proj_code = projectList[i].proj_code;//遍历当前可用项目编码
      pane.push(
        <TabPane tab={projectList[i].proj_name} key={i}>
          <Row>
            <FormItem
              label="活动类型"
              {...formItemLayout}
            >
              <CheckboxGroup
                options={options}
                onChange={onChange.bind(this)}
              />
            </FormItem>
          </Row>
          <Row>
            <Table dataSource={this.state.checked} columns={columns} pagination={false}/>
          </Row>
        </TabPane>
      )
    }


    return (
      <div className='fillContainer'>
        <Form layout={formLayout}>
          <Row>
            <FormItem
              label="本周工时"
              {...formItemLayout}
            >
              <span>{currentWeek.begintime + ' 至 ' + currentWeek.endtime}</span>
            </FormItem>
            <FormItem
              label="工作总时"
              {...formItemLayout}
            >
              <span>39</span>
            </FormItem>
          </Row>

          <Tabs defaultActiveKey="0">
            {pane}
          </Tabs>


          <Row>
            <FormItem {...buttonItemLayout}>
              <Button type="primary" onClick={this.onSaveSubmit.bind(this)}>保存</Button>
            </FormItem>
          </Row>


        </Form>
      </div>
    )
  }
}

function mapStateToProps(state) {
  const {projectList, activityType, activityType2, currentWeek} = state.timeManagement;
  return {projectList, activityType, activityType2, currentWeek}
}

export default connect(mapStateToProps)(Fill);
#2

没有仔细看代码,你可以看一下官方文档,column里面有个render的参数,可以定位到当前行的值,不知道能不能帮到楼主

1 Like