当前位置: 首页 > 知识库问答 >
问题:

React动态表和嵌套映射

牛嘉谊
2023-03-14

我必须做一个用户/权限表,其中“权限”是X轴,“用户”是Y轴。表的其余部分由复选框填充,这些复选框指示X用户是否具有Y权限。这两个都是动态长度,每个API都可以访问另一个API。即:权限API为每个权限,具有该权限的用户数组。此外,用户API为每个用户,用户拥有的权限数组。

>

  • 我有嵌套贴图的问题,我觉得这样做很昂贵?(如果有40个权限和350个用户,我们将讨论14k复选框)

    如何为每个复选框保存状态?没关系,我想用支票做什么?我还需要一种html" target="_blank">方法来发送更新的权限到另一个API。

    使用返回语句中的“isChecked”常量,我强制复选框只能是真或假,单击时无法更改。

    在return语句中,我应该映射“checks”,但由于某些原因,并没有像我期望的那个样填充。

    [{userID:number,permID:number,checked:boolean},{userID:number,permID:number,checked:boolean}等]

    代码看起来像这样:

    const [checks, setChecks] = useState([]);
    
    const users = //GET to users API
    const permissions = //GET to permissions API
    
      const mapPermissions = () => {
        users.map((user: any) => {
          permissions.map((permission: any) => {
            setChecks((prevState: any) => [
              ...prevState,
              {
                userID: user.id,
                permID: permission.id,
                //group_lists is an array of Permissions ID that current user has.
                checked: user.group_lists ? user.group_lists.includes(permission.id) : false,
              },
            ]);
          });
        });
      };
    
      useEffect(() => {
        mapPermissions();
      }, []);
    
    return (
        <TableContainer component={Paper}>
          <Table className={styles.table}>
            <TableHead>
              <TableRow>
                <TableCell className={styles.blank} />
                {permissions.map((permission) => (
                  <TableCell key={permission.id} className={styles.header}>
                    {permission.name}
                  </TableCell>
                ))}
              </TableRow>
            </TableHead>
            <TableBody>
    
    // Should be replacing this for "checks" state map.
    
                  {users.map((user: any) => (
                    <TableRow key={user.id}>
                      <TableCell
                        className={styles.left}
                      >{`${user.first_name} ${user.last_name} (${user.username})`}</TableCell>
                    {permissions.map((permission: any) => {
                    const isChecked = user.group_lists
                      ? user.group_lists.includes(permission.id)
                      : false;
    
                    return (
                      <TableCell key={`${user.id}-${permission.id}`}>
                        <input
                          type="checkbox"
                          checked={isChecked}
                          onChange={(e: ChangeEvent<HTMLInputElement>) => {
                            console.log({
                              user: user.id,
                              permid: permission.id,
                              currentState: isChecked,
                              futureState: e.target.checked,
                            });
                          }}
                        />
                      </TableCell>
                    );
                  })}
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </TableContainer>
      );
    

    如果需要,我愿意删除所有内容。提前感谢:)

  • 共有1个答案

    苗烈
    2023-03-14

    我简化了您的代码片段,使之更简单。我会选择这样的

    type UpdatesType = {
      userId: number;
      permissionId: number;
      operation: 'add' | 'remove';
    }
    export const UserPermissionTable: React.FC = ({}) => {
      const [updates, setUpdates] = useState<UpdatesType[]>([]);
      const users =  // get from api
      const permissions =  // get from api
    
      return (
        <div>
          <table>
            <thead>
              <tr>
                <td />
                {permissions.map((permission) => (
                  <td key={permission.id}>{permission.name}</td>
                ))}
              </tr>
            </thead>
            <tbody>
              {users.map((user: any) => (
                <tr key={user.id}>
                  <td>{`${user.name}`}</td>
                  {permissions.map((permission: any) => {
                    const isChecked = user.group_lists
                      ? user.group_lists.includes(permission.id)
                      : false;
    
                    return (
                      <td key={`${user.id}-${permission.id}`}>
                        <input
                          type="checkbox"
                          defaultChecked={isChecked}
                          onChange={(e) => {
                            setUpdates((prev) => [
                              ...prev,
                              {
                                userId: user.id,
                                permissionId: permission.id,
                                operation: e.target.checked ? "add" : "remove",
                              },
                            ]);
                          }}
                        />
                      </td>
                    );
                  })}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      );
    };
    

    重点:

    1. 你不需要自己处理每个复选框的状态,你可以使用defaultChecked属性,只需在复选框更改上更新你的更新对象
    2. 在我的例子中,我把所有的更新都放在一个数组中,然后你可以把这个数组和操作一起发送到任何你想要的地方——你也可以在发送到应用编程接口之前删除重复的操作,但这不是这个问题的目的
     类似资料:
    • 问题内容: 我正在尝试为如下对象创建动态映射: 我希望属性为嵌套类型,该类型是我在下面的映射中使用nested_feature模板定义的,并且按预期工作。但是,我也想让属性的嵌套对象中的每个属性都带有定义的其他属性。我尝试了第二个nested_template模板,但没有成功。 不幸的是,属性中的属性是从另一个进程创建的,几乎可以是任何名称/值对。关于如何使用动态模板将属性设置为嵌套的任何建议,以

    • 我试图为对象创建一个动态映射,如下所示:

    • 问题内容: 我有以下路由配置: GuaranteeLoggedInContainer为: 但是,历史的推动力:没有用。这里没有历史。 如果我使用这样的配置: 我遇到类似的问题: reactjs中最好的身份验证方法是什么? 问题答案: 从我对您的React Router设计的了解中,您似乎正在使用React Router版本4 在这种情况下,您可以在组件本身中指定路由,并利用withRouter进行

    • 我有一个方法可以返回相当嵌套的JSON,比如: 当我尝试使用< code>JsonSlurper将这个JSON slurp到< code>def result中时,我得到了异常: 当<code>parseText</code>执行时产生引发的异常: 有什么办法吗?

    • 我正在构建一个RESTAPI,它接受用户以以下JSON格式输入的内容。细节是嵌套的JSON对象,其键值是动态的,其关联的数据类型也是动态的。如下图所示,颜色是字符串列表,ram是整数列表,值可以是字符串、布尔值和整数类型。考虑到具体情况,如何构建请求POJO类将请求JSON转换为请求对象在键、值及其数据类型方面是动态的。在下面的JSON中,细节可以有0。。n键值,其值数据类型可以是字符串列表、整数

    • 我不确定如何将嵌套的结果集映射到域实体中。 以下是我想做的事情的大概想法: 2张桌子 域实体(包含嵌套列表) LoanEntity.java Book.java 持久实体 Loans.java Dao.xml(不知道如何映射它,尝试使用一个) 注意:此查询将复制找到的#本书的记录。 LoanMapper.java 下面的错误是我得到的: 错误:结果类型中的未知属性“books.bookName”c