将可点击 table 行中的数据动态显示到模式中

Dynamically displaying data from a clickable table row into a modal

我正在尝试创建一个由数据行组成的组件,单击该组件时,会打开一个模式,其中包含与该 table 行相关的信息。例如,当用户单击 "team 1" 时,会出现一个模式,显示一个新的 table,显示分配给该团队的每个用户。

我已经设法使用手动提供的参数实现了这一点,但是我不知道如何根据单击的 table 行使模态动态显示数据。 Here is a link to a jsfiddle that i've made to show my problem.

    getInitialState: function () {
    return {
      teams:[
        {
          id: '1',
          teamName: 'team 1',
          users: ['dave', 'steve', 'jim', 'barry', 'tom', 'harry']
        },
      ]
    };


    render: function () {
    var self = this;
    var projectsTable = this.state.teams.map(function (obj, index) {
      return (
        <tr className="table-teamProject" key={index} data-toggle="modal" data-target="#projectUsersModal" data-id='3'>
          <div className="mCellsContainer">
            <div className="mCellsNames">{obj.teamName}</div>
            <div className="mCellsCount">{obj.users.length} Users</div>
          </div>
        </tr>
      );
    });

    var projectUsersModal = this.state.teams.map(function (obj, index) {
      return (
        <div className="modal projectUsersModal fade" id="projectUsersModal" tabIndex={-1} role="dialog" aria-labelledby="myModalLabel">
          <div className="modal-dialog" role="document">
            <div className="modal-content">
              </div>
            </div>
          </div>
      );
    });

    return (
      <div>
        <div className="projectsColContainer">
          <div className="panel panel-default">
            <div className="panel-heading">Projects</div>
            <table className="scroll-table">
              {projectsTable}
              {projectUsersModal}
            </table>
          </div>
        </div>
      </div>
    );
  }

render() 方法正在创建,我认为是,为团队数组中的每个团队创建一个隐藏模式,无论用户是否请求显示模式(单击团队的link) 或不。更好的方法是按需创建特定模式,即当用户单击团队的 link.

这可以通过创建点击处理程序来完成,在该函数中,您可以通过设置模态所在团队的 ID 来修改状态,如下所示:

onClickTeam: function(teamId) {
  this.setState({ 
    openModalTeamId: this.state.openModalTeamId == teamId ? null : teamId 
  });
}

然后在你的 render() 方法中你会想要检查这个 openModalTeamId 状态 属性 是否有一些价值,如果是的话,因为你在那里存储团队的 ID ,您可能希望使用 Array.prototype.find 在您的状态团队数组中查找这个特定的团队,然后使用返回的结果来构建您的模态内容。

render: function() {
  ...

  var modalBody;
  if (this.state.openModalTeamId) {
    var team = this.state.teams.find(function(el) {
      return el.id == self.state.openModalTeamId 
    });

    modalBody = 
      ...
      <div className="modal-body">
        Lets assume this is your modal containing the 
        following info about the selected team:
        <br /><br />
        {JSON.stringify(team)}
        <br /><br />
        <div onClick={(this.onClickTeam.bind(this, team.id))}>
          Click me to close
        </div>
      </div>
      ...
  }

  ...
}

一旦你有了它,你就可以将这个新的 modalBody 变量附加到渲染的 JSX 中,就像你在代码中使用 projectUsersModal 变量一样。如果没有团队被点击,那么这个变量将是 undefined 并且不会显示任何模式。

return (
  <div>
    <div className="projectsColContainer">
      <table className="scroll-table">
        {projectsTable}
        {modalBody}
      </table>
    </div>
  </div>
);

jsFiddle

您可以使用 https://github.com/fckt/react-layer-stack .

它允许您使用闭包中的变量(如果您将它提供给 Layer 的 "use" 属性,它会自动传播)并且还可以将事件数据从切换设置为模态 window。你也可以有 "stack" 个带 zIndex 的层,一个在另一个上。

import { Layer, LayerContext } from 'react-layer-stack'
// ... for each `object` in array of `objects`
const modalId = 'DeleteObjectConfirmation' + objects[rowIndex].id
return (
    <Cell {...props}>
        // the layer definition. The content will show up in the LayerStackMountPoint when `show(modalId)` be fired in LayerContext
        <Layer use={[objects[rowIndex], rowIndex]} id={modalId}> {({
            hideMe, // alias for `hide(modalId)`
            index } // useful to know to set zIndex, for example
            , e) => // access to the arguments (click event data in this example)
          <Modal onClick={ hideMe } zIndex={(index + 1) * 1000}>
            <ConfirmationDialog
              title={ 'Delete' }
              message={ "You're about to delete to " + '"' + objects[rowIndex].name + '"' }
              confirmButton={ <Button type="primary">DELETE</Button> }
              onConfirm={ this.handleDeleteObject.bind(this, objects[rowIndex].name, hideMe) } // hide after confirmation
              close={ hideMe } />
          </Modal> }
        </Layer>

        // this is the toggle for Layer with `id === modalId` can be defined everywhere in the components tree
        <LayerContext id={ modalId }> {({showMe}) => // showMe is alias for `show(modalId)`
          <div style={styles.iconOverlay} onClick={ (e) => showMe(e) }> // additional arguments can be passed (like event)
            <Icon type="trash" />
          </div> }
        </LayerContext>
    </Cell>)
// ...