Expand row by column : 按多列展开行,根据点击的列加载不同的组件

Expand row by column : Expand row by multiple columns and load different components according to the column clicked

我正在按照下面的示例来实现 "expand row by column"。

/* eslint max-len: 0 */
import React from 'react';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';

const products = [];

function addProducts(quantity) {
  const startId = products.length;
  for (let i = 0; i < quantity; i++) {
    const id = startId + i;
    if (i < 3) {
      products.push({
        id: id,
        name: 'Item name ' + id,
        price: 2100 + i,
        expand: [ {
          fieldA: 'test1',
          fieldB: (i + 1) * 99,
          fieldC: (i + 1) * Math.random() * 100,
          fieldD: '123eedd' + i
        }, {
          fieldA: 'test2',
          fieldB: i * 99,
          fieldC: i * Math.random() * 100,
          fieldD: '123eedd' + i
        } ]
      });
    } else {
      products.push({
        id: id,
        name: 'Item name ' + id,
        price: 2100 + i
      });
    }
  }
}
addProducts(5);

class BSTable extends React.Component {
  render() {
    if (this.props.data) {
      return (
        <BootstrapTable data={ this.props.data }>
          <TableHeaderColumn dataField='fieldA' isKey={ true }>Field A</TableHeaderColumn>
          <TableHeaderColumn dataField='fieldB'>Field B</TableHeaderColumn>
          <TableHeaderColumn dataField='fieldC'>Field C</TableHeaderColumn>
          <TableHeaderColumn dataField='fieldD'>Field D</TableHeaderColumn>
        </BootstrapTable>);
    } else {
      return (<p>?</p>);
    }
  }
}

export default class ExpandRow extends React.Component {
  constructor(props) {
    super(props);
  }

  isExpandableRow(row) {
    if (row.id < 3) return true;
    else return false;
  }

  expandComponent(row) {
    return (
      <BSTable data={ row.expand } />
    );
  }

  render() {
    const options = {
      expandRowBgColor: 'rgb(242, 255, 163)',
      expandBy: 'column'  // Currently, available value is row and column, default is row
    };
    return (
      <BootstrapTable data={ products }
        options={ options }
        expandableRow={ this.isExpandableRow }
        expandComponent={ this.expandComponent }
        search>
        <TableHeaderColumn dataField='id' isKey={ true }>Product ID</TableHeaderColumn>
        <TableHeaderColumn dataField='name' expandable={ false }>Product Name</TableHeaderColumn>
        <TableHeaderColumn dataField='price' expandable={ false }>Product Price</TableHeaderColumn>
      </BootstrapTable>
    );
  }
}

问题: 我想在 "multiple columns" 上实施扩展行。例如:

我会用 3 列中的 2 列来扩展行。

产品编号 产品名称 产品价格

我想要的行为是:

1.) 当用户点击 "product id" 列时,我想像上面那样显示其他一些 BSTTableNew 组件(在展开行上),但列 "field A" & "field B" 和一些其他功能。

2.) 当用户点击 "product name" 列时,我想显示与上面类似的 BSTTable(在展开行上)。

我必须在下面的代码中进行哪些更改才能根据我单击以展开包含更多详细信息的行的列加载相应的组件class?

我相信我必须对下面的代码进行一些更改才能加载其他组件:

expandComponent(row) {

if( column === "productID") { //something of this sort I want
  return (
    <BSTableNew data={ row.expand } />
  );
}

if( column === "productName") {  //something of this sort I want
  return (
    <BSTable data={ row.expand } />
  );
}
}

如何实现以上?

react-bootstrap-table 已弃用,您应该使用 react-bootstrap-table2


如果我理解正确的话,你想展开行,但是展开的内容应该不同,这取决于column/cell点击。

第 1 - 扩展行

'Expand Management'例子为基础,我们可以看到如何在状态中使用数组来控制展开的行。这很简单,但我们不能使用 onExpand 处理程序,因为它不依赖于列。我们可以使用 expanded 选项:

expanded: this.state.expanded,

此数组仅包含展开的行索引。

第 2 - 单击了哪一列?

示例包含 'Column Event' - onClick 获取我们需要的 column 参数。此事件必须在 columns、f.e 中定义。像:

const columns = [{
  dataField: 'id',
  text: 'Product ID',
  events: {
    onClick: (e, column, columnIndex, row, rowIndex) => {
      console.log(row, column);
      const isRowExpanded = this.state.expanded.includes( row );
      this.setState( {
        column: 'id',
        expanded: isRowExpanded ? 
          this.state.expanded.filter(x => x !== row)
          : [...this.state.expanded, row]
      });
    }
  }
}, {
  dataField: 'name',
  text: 'Product Name',
  events: {
    onClick: (e, column, columnIndex, row,     rowIndex) => {
      console.log(row, column);
      const isRowExpanded =     this.state.expanded.includes( row );
      this.setState( {
        column: 'name',
        expanded: isRowExpanded ? 
          this.state.expanded.filter(x => x !== row)
          : [...this.state.expanded, row]
      });
    }
  }
}, {
  dataField: 'price',
  text: 'Product Price'
}];

这样我们就可以同时处理 - 展开的行和最后点击的列。

第 3 - 显示适当的组件

我们只需要扩展渲染器参数化:

const expandRow = {
  renderer: row => {
    if (this.state.column==='id') {
      return (
        <ColumnIDClickedTable someParam={someData[row]} />
      )
    } else {
      return <ColumnNameClickedTable />
    }
  },

应该就这些了。 只为前 3 行可扩展添加条件是一项简单的任务。 所有展开的行都将更改列更改的内容 - 仅最后一次点击保存。如果您需要单独的行行为,请将列保存在索引数组中。