通过使用选中固定数据-table 中的所有框?

Check all boxes in a fixed-data-table by using?

我在函数 checkall 中使用 jquery check/uncheck 固定数据的特定列中的所有复选框 - table。我想知道这是否是最好的方法,或者是否有 "react-way" 这样做?

'use strict';

var React = require('react/addons');
var Table = require('fixed-data-table').Table;
var Column = require('fixed-data-table').Column;

// Table data as a list of array.
var rows = [
  ['a1', 'b1', 'c1'],
  ['a2', 'b3', 'c2'],
  ['a3', 'b3', 'c3'],
];

function checkBox(data){
  return (
    <input type="checkbox" value={data} className="kill-checkbox" />
  );
}

function rowGetter(rowIndex) {
  return rows[rowIndex];
}

// Fixed data tables (Facebook) requirement:http://facebook.github.io/fixed-data-table/
require('../../styles/fixed-data-table.css');
var TableTester = React.createClass({
  render: function () {
    return (
      <div>
        <label>Check All</label>&nbsp;<input type="checkbox" id="check-all" onClick={this.checkall} />
        <Table rowsCount={rows.length} width={1000} height={300} headerHeight={50} rowHeight={50} rowGetter={rowGetter}>
          <Column label="Col 1" width={500} dataKey={0} />                                                            
          <Column label="Col 2" width={500} dataKey={1} cellRenderer={checkBox} align="center" />
        </Table>
      </div>
    );
  },

  checkall:function(){
    var checked = $("#check-all").is(':checked');    
    $(".kill-checkbox").each(function(){
      $(this).prop('checked', checked);
    });
  },  

});

module.exports = TableTester;

这取决于选中或未选中的复选框在您的应用程序中的含义以及您何时需要此信息。以这种方式有效地将状态放入 DOM 中,当您稍后需要该信息时,您将不得不返回到 DOM 来获取它。

另一种方法是使用一些数据来表示或可用于导出每个复选框的选中状态,并使用它来设置其 checked 属性。然后,您需要实施适当的事件处理程序以根据用户的操作适当地更新数据。

例如,如果您要显示具有关联值的复选框网格,您可能有一个 selectedValues 列表。为了方便创建示例代码,我们将把它放在组件自己的状态中,但这可能会作为道具出现,或者住在商店里,或者...

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

然后您可以使用所选值列表导出每个复选框的 checked 状态:

renderCheckbox(data) {
  var checked = this.state.selectedvalues.indexOf(data) != -1
  return <input type="checkbox" value={data} checked={checked}/>
}

in render(): cellRenderer={this.renderCheckbox}

但是现在您的复选框是只读的,因为您还没有实施更改 selectedValues 以响应其上的事件,所以让我们这样做:

_onCheckboxChange(e) {
  var {selectedValues} = this.state
  var {checked, value} = e.target
  if (checked) {
    selectedValues.push(value)
  }
  else {
    selectedValues.splice(selectedValues.indexOf(value), 1)
  }
  this.setState({selectedValues})
},

renderCheckbox(data) {
  var checked = this.state.selectedValues.indexOf(data) != -1
  return <input type="checkbox" value={data} checked={checked} onChange={this._onCheckboxChange}/>
}

现在要实现类似 select/deselect all 切换的功能,您需要实现一个事件处理程序,它会进行适当的数据更改并导致组件重新呈现:

_onCheckAll(e) {
  var selectedValues
  if (e.target.checked) {
    // Set all the available values as selected - using the rows variable
    // from your question to put something meaningful here.
    selectedValues = rows.reduce((all, row) => all.concat(row))
  }
  else {
    selectedValues = []
  }
  this.setState({selectedValues})
}

我想这意味着 "React way" 是根据数据对您的 UI 进行建模,而不是您希望看到的最终结果,在本例中是 "which of the values I'm displaying are selected?" 与 "which checkboxes are checked?"

正如所承诺的那样,我有一个基于固定数据-table 问题中提供的 solution/explanation 的工作示例:https://github.com/facebook/fixed-data-table/issues/70

'use strict';

var React = require('react/addons');
var Table = require('fixed-data-table').Table;
var Column = require('fixed-data-table').Column;

var dataKey = 1; // key to store in selected in the sets below it represents the values [b1|b2|b3] as in index 1 

// Fixed data tables (Facebook) requirement:http://facebook.github.io/fixed-data-table/
require('../../styles/fixed-data-table.css');
var TableTester = React.createClass({

  getInitialState: function(){
    return ({
      selected:[],
      rows: [
        ['a1', 'b1', 'c1'],
        ['a2', 'b2', 'c2'],
        ['a3', 'b3', 'c3'],
      ]      
    })
  },

  render: function () {
    var data = this.state.rows;

    return (
      <div>
        <label>Check All</label>&nbsp;<input type="checkbox" onClick={this._toggleAll} />
        <Table rowsCount={data.length} rowGetter={this._rowGetter} onRowClick={this._onRowSelect} width={1000} height={300} headerHeight={50} rowHeight={50}>
          <Column label="Col 1" width={500} dataKey={0} />                                                            
          <Column label="Col 2" width={500} dataKey={dataKey} align="center" 
            cellRenderer={(value) => <input type="checkbox" value={value} checked={this.state.selected.indexOf(value) >= 0} onChange={() => {}} />}/>
        </Table>
      </div>
    );
  },

  _toggleAll:function(e){
    var newSet = [];
    if (e.target.checked) {
      this.state.rows.forEach(function(columns){
        newSet.push( columns[1] );
      });
    }
    this.setState({
      selected: newSet
    });

  },

  _onRowSelect: function(e, index) {
    var value = this.state.rows[index][dataKey];
    var newSet = this.state.selected;
    if ( newSet.indexOf(value) < 0 ) { // does not exist in list
      newSet.push(value);
    } else {
      newSet.splice(newSet.indexOf(value), 1);
    }  
    this.setState({
      selected: newSet
    });

  },  

  _rowGetter: function(rowIndex){
      return this.state.rows[rowIndex];
  }

});

module.exports = TableTester;