表 - 删除某些行后,下一行将变为/保持选中状态

时间:2017-03-31 03:11:26

标签: reactjs material-ui

当我在表格中删除一些行时,接下来的行将保持选中状态。

在我的stateselectedStudentstableDataselectedStudents是我表中的所有选定索引。

当我点击删除按钮时,以下代码会移除tableData中的所有行以及selectedStudents中的所有值。

let diff = _.remove(this.state.tableData, (it, idx) => !~this.state.selectedStudents.indexOf(idx))
this.setState({ tableData: diff, selectedStudents: [] })

问题是删除了行,但选择了下一行,我不知道为什么

enter image description here See full image with states details here

这是此组件的完整代码......或check in WebPack bin

export default React.createClass({

    getInitialState: function() {
        return {
            selectedStudents: [],
            tableData: [
                { name: 'John Smith' },
                { name: 'Randal White' },
                { name: 'Stephanie Sanders' },
                { name: 'Steve Brown' },
                { name: 'Joyce Whitten' },
                { name: 'Samuel Roberts' },
                { name: 'Adam Moore' }
            ]
        }
    },

    // Methods
    _onStudentSelected (selected) {
        let selectedObjs = []
        if (_.isArray(selected)) { // Multiples selections
            selectedObjs.push(...selected)
        } else if (_.isNumber(selected)) { // One Selection
            selectedObjs.push(selected)
        } else if (_.isString(selected) && selected === 'all') { // Select all elements
            selectedObjs.push(...this.state.tableData.map((it, idx) => idx))
        } // None selected

        this.setState({ selectedStudents: selectedObjs })
    },

    _onClickDeleteStudent () {
        let diff = _.remove(this.state.tableData, (it, idx) =>
            !~this.state.selectedStudents.indexOf(idx))

        this.setState({ tableData: diff, selectedStudents: [] })
    },


    render: function() {
        return (
        <Table fixedHeader multiSelectable onRowSelection={this._onStudentSelected}>
            <TableBody deselectOnClickaway={false}>
                {this.state.tableData.map((row, index) => (
                    <TableRow key={row.name} selected={this.state.selectedStudents.indexOf(index) !== -1}>
                        <TableRowColumn>
                            <TextField value={row.name} hintText='Name' />
                        </TableRowColumn>
                        <TableRowColumn>
                            <TextField hintText='Password' type='password' />
                        </TableRowColumn>
                    </TableRow>
                ))}
            </TableBody>
            <TableFooter adjustForCheckbox>
                <TableRow>
                    <TableRowColumn>
                        <RaisedButton label='Delete' onClick={this._onClickDeleteStudent}
                                      disabled={this.state.selectedStudents.length <= 0} />
                    </TableRowColumn>
                </TableRow>
            </TableFooter>
        </Table>
        );
    }
});

版本

包裹|版本
----------- ------------------------------------
材料-ui | ^ 0.17.1
反应| ^ 15.4.2
浏览器| Chrome版本56.0.2924.87(64位)

ADDED

报告为issue 6496

上的错误

3 个答案:

答案 0 :(得分:0)

这是您示例的简化现代重构版本:

import React, {Component} from 'react'
import Table from 'material-ui/Table/Table'
import TableBody from 'material-ui/Table/TableBody'
import TableHeader from 'material-ui/Table/TableHeader'
import TableFooter from 'material-ui/Table/TableFooter'
import TableHeaderColumn from 'material-ui/Table/TableHeaderColumn'
import TableRow from 'material-ui/Table/TableRow'
import TableRowColumn from 'material-ui/Table/TableRowColumn'
import TextField from 'material-ui/TextField/TextField'
import RaisedButton from 'material-ui/RaisedButton/RaisedButton'

export default class MyTable extends Component {

  state = {
    selectedStudents: [],
    tableData: [
      { id: 0, name: 'John Smith' },
      { id: 1, name: 'Randal White' },
      { id: 2, name: 'Stephanie Sanders' },
      { id: 3, name: 'Steve Brown' },
      { id: 4, name: 'Joyce Whitten' },
      { id: 5, name: 'Samuel Roberts' },
      { id: 6, name: 'Adam Moore' }
    ]
  }

  // Methods
  _onStudentSelected = (selected) => {
    let selectedStudents = selected === 'all'// Select all elements
      ? [...this.state.tableData].map(({id}) => id)
      : selected

    console.log('selected', selected,
                '\nSelected students', selectedStudents)

    this.setState({selectedStudents})
  }

  _onClickDeleteStudent = () => {
    let tableData = this.state.tableData.filter(({id}) =>
      !this.state.selectedStudents.includes(id)
    )

    this.setState({tableData, selectedStudents: []}, () => {
      console.log('After delete', this.state.tableData,
                '\nthis.state.selectedStudents', this.state.selectedStudents)
    })
  }

  render () {
    console.debug('rendered selectedStudents', this.state.selectedStudents)
    const isSelected = id => {
      let result = this.state.selectedStudents.includes(id)
      console.log('id', id, 'result', result)
      return result
    }
    return (
      <Table fixedHeader multiSelectable enableSelectAll onRowSelection={this._onStudentSelected}>
        <TableHeader>
          <TableRow>
            <TableHeaderColumn>Name</TableHeaderColumn>
            <TableHeaderColumn>Password</TableHeaderColumn>
          </TableRow>
        </TableHeader>
        <TableBody deselectOnClickaway={false}>
          {this.state.tableData.map(({id, name}) => (
            <TableRow key={id} selected={isSelected(id)}>
              <TableRowColumn>
                <TextField value={name} hintText='Name' />
              </TableRowColumn>
              <TableRowColumn>
                <TextField hintText='Password' type='password' />
              </TableRowColumn>
            </TableRow>
          ))}
        </TableBody>
        <TableFooter adjustForCheckbox>
          <TableRow>
            <TableRowColumn>
              <RaisedButton label='Delete' onTouchTap={this._onClickDeleteStudent}
                            disabled={!this.state.selectedStudents.length} />
            </TableRowColumn>
          </TableRow>
        </TableFooter>
      </Table>
    )
  }
}

希望它有所帮助尽管它没有解决你的问题。您应该在Material-UI repo中提出一个问题。

答案 1 :(得分:0)

在当前稳定版本16.7,表组件的onRowSelection(索引)中,索引在删除最后一行后不反映正确的状态。您可以通过以下方式检查固定版本:npm install --save material-ui @ next,但到目前为止它仍在测试中。欢呼声。

编辑: M.Quan改变了源代码,顺便说一句,它对我来说没问题。 请参阅https://github.com/callemall/material-ui/issues/6006

“我在第131行找到了错误的原因 https://github.com/callemall/material-ui/blob/master/src/Table/TableBody.js

componentWillReceiveProps(nextProps) {
    if (this.props.allRowsSelected !== nextProps.allRowsSelected) {
        if (!nextProps.allRowsSelected) {
            this.setState({
              selectedRows: [],
            });
        } else {
            this.setState({
                selectedRows: this.calculatePreselectedRows(nextProps),
            });
        }
    }
}

当我使用版本0.16.6中的代码更改代码时。它与我合作!

componentWillReceiveProps(nextProps) {
    if (this.props.allRowsSelected && !nextProps.allRowsSelected) {
        this.setState({
            selectedRows: this.state.selectedRows.length > 0 ?
            [this.state.selectedRows[this.state.selectedRows.length - 1]] : [],
        });
        // TODO: should else be conditional, not run any time props other than allRowsSelected change?
    } else {
        this.setState({
            selectedRows: this.calculatePreselectedRows(nextProps),
        });
    }
} 

答案 2 :(得分:-2)

请使用onTouchTap而不是onClick