【问题标题】:Retrieve row value selected in a Table as an array and send the results to another function on React检索表中选择的行值作为数组并将结果发送到 React 上的另一个函数
【发布时间】:2017-11-13 00:09:12
【问题描述】:

如何控制台记录表组件上显示的选定值,然后存储我的选择并将其传递给第二个函数?

我有一个表格显示来自我的 API 的数据,表格的每一行都有复选框。我正在为 React 使用

Material UI 组件。

根据文档,onRowSelection(类似于 onClick)属性应该给我一个选定行的数组(只有索引),例如,如果我选择第一行,控制台将打印 [0],如果我选择了第一个和第五个,控制台会打印 [0,4]

现在,提供表格的数据来自我的状态,这几乎是来自我的 API 的数据 this.state.dataTable = response.data(请参阅最后的代码)

所以看起来它正在循环通过 this.state.dataTable 并且没有考虑触发事件。我做错了什么?

在我做的 onRowSelection 里面的函数上:

   handleRowSelection (i) {

       for (let x = 0, len = i.length; x < len; x++) {
         i = this.state.dataTable[x];
         console.log(i);
       }
   }

我首先认为它提供了正确的价值。当我单击第一个复选框(行)时,它给出了第一行元素的值,但是当我单击第 6 个复选框时,它给出了第二行元素的值,第 7 个复选框 = 第三个元素,依此类推。

我也试过了

handleRowSelection (row) {

    const selectedRows = []
    this.state.dataTable.forEach((row, i) => {
    row = row.indexOf(i) > -1

    selectedRows.push(row)
}
    console.log(selectedRows)

这给了我一个有趣的值,例如:[false, false, false, true, false, false, true]

不用说,true 值代表我选择的复选框

代码(跳到课程开始)

    import ...
    import {Table, TableBody, TableHeader, TableHeaderColumn, TableRow, 
    TableRowColumn} from "material-ui/Table";

    const REAL_URL = `//xx.xx.xx.xx/getData/`;

    const markers = [
      {
        key: "Q123456789",
        position: [37.786464, -122.411047],
        children: "My first popup"
      },
      {
        key: "P234567890",
        position: [40.689192, -74.044563],
        children: "My second popup"
      }
    ];


    const MyPopupMarker = ({ children, position, index, handleToggle }) => (
      <Marker onClick={() => handleToggle(index)} position={position}>
        <Popup>
          <span>{children}</span>
        </Popup>
      </Marker>
    );

    const MarkerList = ({ markers, handleToggle }) => {
      const items = markers.map(({ key, ...props }, i) => (
        <MyPopupMarker key={key} {...props} index={i} handleToggle={handleToggle} />
      ));
      return <div>{items}</div>;
    };

      // var holdArray = []

    class Mapper extends Component {
      constructor(props) {
        super(props);

        this.handleToggle = this.handleToggle.bind(this);
        this.handleRowSelection = this.handleRowSelection.bind(this);
        this.handleClose = this.handleClose.bind(this);
        this.handleDeploy = this.handleDeploy.bind(this);

        this.state = {
          lat: 29.761993,
          lng: -95.366302,
          zoom: 4,
          open: false,
          places: [],
          selectedMarker: null,
          selectable: true,
          multiSelectable: true,
          enableSelectAll: true,
          dataTable: [],
          selectedRows: []
        };
      }

      componentDidMount() {
        this.setState({
          places: markers
        });
      }

      handleToggle(index) {
        const self = this;
        const selectedMarker = this.state.places[index];

        this.setState({
          open: !this.state.open,
          selectedMarker: selectedMarker
        });

        const LAST_URL = REAL_URL + this.state.selectedMarker.key;

        axios
          .get(LAST_URL)
          .then(response => {
            self.setState({
              dataTable: response.data
            });

            console.log(response.data);
          })
          .catch(function(error) {
            console.log(error);
          });
      }

      handleRowSelection (i) {

          for (let x = 0, len = i.length; x < len; x++) {
            i = this.state.dataTable[x];
            console.log(i);
          }
      }


      handleDeploy () {

        let resultObject = {
          "devices": this.state.selectedMarker.key,
          // "app": this.handleRowSelection()
        }
        // console.log(resultObject)

      }

  render() {
    const center = [this.state.lat, this.state.lng];
    const selectedMarker = this.state.selectedMarker;

    let availableRows = this.state.dataTable.map((row, k)=>{
      return (
        <TableRow key={k} selected={row.selected}>
          <TableRowColumn>{row}</TableRowColumn>
          <TableRowColumn>Unknown</TableRowColumn>
        </TableRow>
      )
    });


    return (
      <div>
        <Map center={center}
          zoom={this.state.zoom}
          minZoom={3}
          style={styles.map}>

          <TileLayer
            url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"
            attribution="&copy; <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors"
          />

          <MarkerList markers={markers} handleToggle={this.handleToggle} />
        </Map>

        <Drawer
          width={500}
          openSecondary={true}
          docked={false}
          open={this.state.open}
          onRequestChange={open => this.setState({ open })}
          containerStyle={styles.whitebox}
        >
          {
            selectedMarker ? (
            <div>
              <Card style={styles.appMedia}>
                <CardTitle
                  titleStyle={styles.drawTitle}
                  subtitleStyle={styles.drawTitle}
                  title={selectedMarker.key}
                  subtitle="Common Field Equipment"
                />
              </Card>

              <Table
                selectable={this.state.selectable}
                multiSelectable={this.state.enableSelectAll}
                onRowSelection={(selectedApps) => this.handleRowSelection(selectedApps, this.props)}
              >

                <TableHeader
                  enableSelectAll={this.state.enableSelectAll}
                  displaySelectAll={false}
                >

                  <TableRow>
                    <TableHeaderColumn>Applications</TableHeaderColumn>
                    <TableHeaderColumn>Status</TableHeaderColumn>
                  </TableRow>

                </TableHeader>


                <TableBody
                  deselectOnClickaway={this.state.clickAway}
                  showRowHover={true}
                >
                  {availableRows}

                </TableBody>

              </Table>

              <RaisedButton
                label="START SELECTED"
                onClick={this.handleDeploy}
                style={styles.buttonStl}
                labelPosition="before"
                backgroundColor="#363636"
                labelStyle={styles.labelStl}
                icon={<BeenHere />}
              />

              <RaisedButton
                label="STOP SELECTED"
                style={styles.buttonStl}
                labelPosition="before"
                backgroundColor="#FF0000"
                labelStyle={styles.labelStl}
                icon={<Cancel />}
              />
            </div>
          ) : null
        }
        </Drawer>
      </div>
    );
  }
}
export default Mapper;

链接到组件http://www.material-ui.com/#/components/table

【问题讨论】:

    标签: javascript arrays reactjs material-ui dom-events


    【解决方案1】:

    在您的 2 个handleRowSelection 示例中,您要么重新定义变量,要么不使用传入的变量。这应该有效:

    handleRowSelection (indexes) {
        const selectedRows = indexes.map(x => this.state.dataTable[x]);
    }
    

    编辑:看起来如果所有行都被选中,那么onRowSelection 将返回字符串“all”,因此需要处理:

    handleRowSelection (indexes) {
        const {dataTable} = this.state;
        const selectedRows = (indexes === 'all')
            ? [...dataTable] // copy of the dataTable
            : indexes.map(x => dataTable[x]);
    }  
    

    编辑

    显示检查复选框的相关代码:

    constructor(props) {
        // ...
        this.state = {
            // ...
            dataTable: [],
            selectedIndexes: []
        }
    }
    
    handleRowSelection (indexes) {
        this.setState({selectedIndexes: indexes});
    }  
    
    render() {
        //...
        let availableRows = this.state.dataTable.map((row, k) => {
          return (
            <TableRow key={k} selected={this.state.selectedIndexes.indexOf(k) !== -1}>
              <TableRowColumn>{row}</TableRowColumn>
              <TableRowColumn>Unknown</TableRowColumn>
            </TableRow>
          )
        });
        //...
    }
    

    【讨论】:

    • omg ,如此简单。谢谢你。您介意告诉我如何将这些值从 console.log (selectedRows) 传递到 handleDeploy 函数吗?我已经尝试过 setState 函数,但它会产生一个错误,它会出于某种原因取消选中复选框
    • 我不确定我是否理解 - 你能从 handleRowSelection 函数中调用 handleDeploy(selectedRows); 吗?
    • handleDeploy () 绑定到 RaisedButton 组件。所以我的想法是首先使用handleRowselection 获取所有行值。一旦我得到了我检查过的所有值,这些值形成了一个数组。我需要将它们传递给handleDeploy()。理想情况下,如果我使用 this.setState({selectedRows:selectedRows}) 并且实际上它可以工作,但是由于某些错误的原因,当我在与 onRowSelection 属性绑定的 handleRowSelection 中使用 seState 时,材料 ui 会取消选择自身,在 Table 组件中跨度>
    • 如果我将handleeploy(selectedRows) 放在handleRowSelection 中,那么它将部署与我在行上的元素一样多的次数,我们不希望这样:(
    • 不,由于 MUI 错误,我认为您需要 selected 道具。有用。查看此示例:codesandbox.io/s/2o8971w40。查看MUITest.js 文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    相关资源
    最近更新 更多