Table - 删除一些行后,选择了下一行 become/stay
Table - After deleting some rows, the next rows become/stay selected
当我在 table 中删除一些行时,选择了下一行 become/stay。
在我的 state
中,我有 selectedStudents
和 tableData
。 selectedStudents
都是在我的table.
中选择的索引
当我点击删除按钮时..下面的代码删除了我的 tableData
中的所有行和 selectedStudents
.
中的所有值
let diff = _.remove(this.state.tableData, (it, idx) => !~this.state.selectedStudents.indexOf(idx))
this.setState({ tableData: diff, selectedStudents: [] })
问题是删除了行但是后面的行被选中了,不知道为什么
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>
);
}
});
版本
包裹 |版本
---------- | ----------------------------------
material-ui | ^0.17.1
反应 | ^15.4.2
浏览器 | Chrome 版本 56.0.2924.87(64 位)
已添加
被报告为 issue 6496
上的错误
这里是您示例的简化现代重构版本:
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 回购中提出问题。
请使用 onTouchTap 而不是 onClick
在当前的稳定版本16.7中,Table组件的onRowSelection(indices),indices在删除最后一行后并没有反映正确的状态。您可以通过 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),
});
}
}
"
当我在 table 中删除一些行时,选择了下一行 become/stay。
在我的 state
中,我有 selectedStudents
和 tableData
。 selectedStudents
都是在我的table.
当我点击删除按钮时..下面的代码删除了我的 tableData
中的所有行和 selectedStudents
.
let diff = _.remove(this.state.tableData, (it, idx) => !~this.state.selectedStudents.indexOf(idx))
this.setState({ tableData: diff, selectedStudents: [] })
问题是删除了行但是后面的行被选中了,不知道为什么
这是该组件的完整代码...或 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>
);
}
});
版本
包裹 |版本
---------- | ----------------------------------
material-ui | ^0.17.1
反应 | ^15.4.2
浏览器 | Chrome 版本 56.0.2924.87(64 位)
已添加
被报告为 issue 6496
上的错误这里是您示例的简化现代重构版本:
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 回购中提出问题。
请使用 onTouchTap 而不是 onClick
在当前的稳定版本16.7中,Table组件的onRowSelection(indices),indices在删除最后一行后并没有反映正确的状态。您可以通过 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),
});
}
}
"