You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为Ant Design表格新增多check属性实现默认选中行的技术问题

数据转换逻辑拆分与异步问题处理

当前基于Ant Design表格的选中行需求,已经实现了给getAllUserRole返回数据添加checkRole数组的逻辑,但现在要完成两个新需求:

  • 针对resProject数据源,先给每条数据添加key字段,再给用户角色数据新增checkProject属性
  • 给getAllUserRole的返回数据再加checkDept数组属性

如果把所有逻辑都堆在getDataUserRole里,代码会混乱不堪,还容易触发异步问题。先看原代码:

async function getDataProject() {
    let resProject = await getAllProject();
    if (resProject) {
      setDataSourceProject(resProject.data);
    }
  }
  
async function getDataUserRole() {

    let resRole = await getAllRoles();
    if (resRole) {
      // 给每个角色添加key
      for (var i = 0; i < resRole.data.length; i++) {
        resRole.data[i]["key"] = i;
      }
      setDataSourceRole(resRole.data);

      let res = await getAllUserRole();
      if (res) {
        console.log("getAllUserRole =", res);
        for (var i = 0; i < res.data.length; i++) {
          // 给每条用户数据添加checkRole数组
          res.data[i]["checkRole"] = [];
          // 遍历当前用户的roleIds数组
          for (var j = 0; j < res.data[i].roleIds.length; j++) {
            // 如果roleIds不为空
            if (res.data[i].roleIds.length != 0) {
              // 遍历所有角色数据,匹配id后把角色的key推入checkRole
              for (var k = 0; k < resRole.data.length; k++) {
                if (res.data[i].roleIds[j] == resRole.data[k].id) {
                  res.data[i]["checkRole"].push(resRole.data[k].key);
                }
              }
            }
          }
        }

        // 如果groupChange为空,直接设置未转换的数据
        if (!(groupChange)) {
          setDataSourceUserRole(res.data);
        }
        // 如果groupChange有值,调用分组函数后设置数据
        else {
          var treeData = groupData(res.data, groupChange)
          setDataSourceUserRole(treeData);
        }
      }
    }
  }

解决思路:拆分逻辑 + 优化异步

1. 抽离通用工具函数

把重复的加key、匹配选中项逻辑单独拎出来,复用性强且代码更整洁:

// 给数组每条数据添加key字段
function addKeyToData(data) {
  return data.map((item, idx) => ({ ...item, key: idx }));
}

// 根据关联数据生成选中的key数组(比如用角色id匹配角色的key)
function getCheckedKeys(targetItem, relationList, targetIdKey, relationIdKey) {
  return relationList
    .filter(relationItem => targetItem[targetIdKey].includes(relationItem[relationIdKey]))
    .map(relationItem => relationItem.key);
}

2. 重构getDataProject

直接在这个函数内完成项目数据的key添加:

async function getDataProject() {
  const resProject = await getAllProject();
  if (resProject) {
    const projectWithKey = addKeyToData(resProject.data);
    setDataSourceProject(projectWithKey);
  }
}

3. 彻底重构getDataUserRole

用Promise.all并行请求所有需要的接口,避免嵌套异步的等待问题,同时拆分三个check属性的生成逻辑:

async function getDataUserRole() {
  // 并行拉取角色、项目、用户角色数据,比串行请求效率更高
  const [resRole, resProject, resUserRole] = await Promise.all([
    getAllRoles(),
    getAllProject(),
    getAllUserRole()
  ]);

  // 任一请求失败则直接返回
  if (!resRole || !resProject || !resUserRole) return;

  // 给角色、项目数据添加key
  const roleWithKey = addKeyToData(resRole.data);
  const projectWithKey = addKeyToData(resProject.data);
  
  setDataSourceRole(roleWithKey);
  setDataSourceProject(projectWithKey);

  // 处理用户角色数据的三个check属性
  const transformedData = resUserRole.data.map((userItem, idx) => {
    return {
      ...userItem,
      key: idx, // 给用户数据也添加key,方便表格操作
      checkRole: getCheckedKeys(userItem, roleWithKey, 'roleIds', 'id'),
      checkProject: getCheckedKeys(userItem, projectWithKey, 'projectIds', 'id'), // 假设用户数据包含projectIds字段,可按需修改
      checkDept: [] // 替换为部门数据的匹配逻辑,格式和上面一致
    };
  });

  // 处理分组逻辑
  const finalData = groupChange ? groupData(transformedData, groupChange) : transformedData;
  setDataSourceUserRole(finalData);
}

优化亮点

  • 职责清晰:每个函数只负责单一功能,避免逻辑堆砌
  • 异步安全:并行请求避免嵌套await的顺序问题,一次性获取所有依赖数据
  • 无副作用:用map和扩展运算符生成新数据,不直接修改接口返回的原始数据,减少意外bug

内容的提问来源于stack exchange,提问作者Jing c

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 17:15:36