无法取消选中并检查单个项目

时间:2016-12-21 06:36:39

标签: javascript reactjs redux

我有一个带复选框的项目列表。单击任何项​​目的复选框时,将显示某些操作(添加,删除,移动等)以将这些操作应用于所选项目。此外,我可以实现check all按钮检查所有项目,也取消选中它。但是,如果我检查一个项目,则在取消选中时,所有项目都会被检查并且相同。

这是我的代码

    var Device = React.createClass({
    getInitialState() {
      return {
        checked: []
      }
    },

    handleChange(e, key) {
      let checked = this.state.checked.slice();
      if (e.target.checked) {
        checked.push(key);
        console.log('checked before removing', checked);
      }
      else {
        checked.splice(checked.indexOf(key), 1);
        console.log('checked after removing', checked);
        // checked.filter((x, i) => checked.splice(checked.indexOf(key), 1));
      }
      this.setState({ checked: checked });
    },

    checkAll() {
      this.setState({
        checked: this.props.devices.entrySeq().map(([key, value]) => key)
      }).toArray();
    },

    uncheckAll() {
      this.setState({ checked: [] });
    },

    render() {
        const { checked } = this.state;
        let devices = this.props.devices.entrySeq().map(([key, value]) => {
        let url = '/device/'+value.get('id');
        let name = value.get('name');
        return (
          <RowGroup key={key}>
              <Row>
                <Cell>
                  <input
                    type="checkbox"
                    name={name}
                    checked={checked.indexOf(key) !== -1}
                    onChange={(e) => this.handleChange(e, key)}
                   />
                </Cell>
                <RouterLink to={url}>
                  <Cell>
                    {name}
                  </Cell>
                </RouterLink>
              </Row>
        </RowGroup>
        );
      }).toArray();

      return (
        <div>
          { checked.length !== 0 ? <DeviceActions uncheckAll={() => this.uncheckAll()} /> :
             <GlobalDeviceActions
               checkAll={() => this.checkAll()}
               uncheckAll={() => this.uncheckAll()}
             />
           }
        <Table>
            {devices}
        </Table>
        </div>
      );
    },
});

const mapDispatchToProps = function(dispatch) {
  return {};
}

const mapStateToProps = createStructuredSelector({
  devices: selectDevices()
});

export default connect(mapStateToProps, mapDispatchToProps)(Device);


const DeviceActions = (props) => (
  <div>
    <Actions>
      <Uncheck onClick={props.uncheckAll} />
      <Add />
      <Move />
    </Actions>
  </div>
);

export const GlobalDeviceActions = (props) => (
  <div>
    <Actions>
      <Check onClick={props.checkAll} />
      <Uncheck onClick={props.uncheckAll} />
    </Actions>
  </div>
);

export default DeviceActions;

使用@Jonny Buchanan的更新代码,一切正常,但是当一次检查所有项目时,我无法取消选中单个项目。我只能一次取消选中整件物品。

更新

现在正在运作。在checkAll函数中,我必须将集合转换为数组。我想,因为集合是生成器,它不会马上执行所以我必须将它变异为数组。

1 个答案:

答案 0 :(得分:1)

如果您保留状态中已检查项目的列表,checkAll()可以设置所有可用的项目键/ ID(或者最适合放入该列表的任何项目),uncheckAll()可以将其设置为一个空列表。

getInitialState() {
  return {
    checked: [],
  }
},

handleChange(e, key) {
  let checked = this.state.checked.slice();
  if (e.target.checked) {
    checked.push(key);
  }
  else {
    checked.splice(checked.indexOf(key), 1);
  }
  this.setState({ checked });
},

checkAll() {
  this.setState({
    checked: this.props.devices.entrySeq().map(([key, value]) => key)
  });
},

uncheckAll() {
  this.setState({ checked: [] });
},

然后在render()中,您可以按输入checked派生:

             <input
                type="checkbox"
                name={name}
                checked={checked.indexOf(key) !== -1}
                onChange={(e) => this.handleChange(e, key)}
               />