【前端Map使用案例】前端多级联动选择-树转数组

文章描述了在前端开发中处理多选/单选二级树数据的场景,通过onChange事件监听,使用Map和递归方法将多级选择的数据从数组转换为扁平化结构。同时,介绍了如何注入额外的remark信息,并提供了相关的处理函数示例。
摘要由CSDN通过智能技术生成

前端数据组装案例

多选/单选的二级树(数组实现)转数组

需求描述

在这里插入图片描述流程节点退回原因为多级选择,可单选也可多选。

  • 退回:一级原因多选,当选中其他时,可手动输入原因作为一级退回原因的补充;
  • 拒绝:一级原因多选,二级原因多选。支持配置为只选一级不选二级,也支持配置为选中一级,全选二级并排除被选中一级。

其中,一级/二级原因的选项为字典值,字典为数组递归定义。

查询字典接口返回数据结构:
在这里插入图片描述

后端需要复杂的动态数据分析,所以数据存储要求扁平化,要求结构为:

在这里插入图片描述

onChange监听处理数组转换问题

问题关键:

  1. 一二级原因既可以多选也可以单选;
  2. 存在二级与一级共存和互斥两种情况;

借助Map递归转化

/**
 * dictToAbReasons
 * @param vals
 */
export const dictToAbReasons = (
  vals: Dict.DictionaryItem[] | Dict.DictionaryItem[][],
) => {
  if (!vals) {
    return;
  }

  const levelMapV1 = new Map<string, Dict.DictionaryItem>();
  const levelMapV2 = new Map<string, Dict.DictionaryItem>();
  const abReasons: Todo.AbnormalReason[] = [];

  for (var i = 0; i < vals.length; i++) {
    if (vals[i][0]) levelMapV1.set(vals[i][0]?.itemId, vals[i][0]);
    if (vals[i][1]) levelMapV2.set(vals[i][1]?.itemId, vals[i][1]);
  }

  if (levelMapV1.size < 1 && levelMapV2.size < 1) {
    levelMapV1.set(vals[0]?.itemId, vals[0]);
    levelMapV2.set(vals[1]?.itemId, vals[1]);
  }

  if (levelMapV2.size > 0) {
    levelMapV2.forEach((x) => {
      if (levelMapV1.get(x?.parentId)) {
        abReasons.push({
          oneLevel: levelMapV1.get(x?.parentId).itemKey,
          oneLevelVal: levelMapV1.get(x?.parentId).itemName,
          secondLevel: x.itemKey,
          secondLevelVal: x.itemName,
        });
      }
    });
  }

  if (abReasons.length < 1 && levelMapV1.size > 0) {
    levelMapV1.forEach((x) => {
      abReasons.push({
        oneLevel: x?.itemKey,
        oneLevelVal: x?.itemName,
      });
    });
  }

  levelMapV1.clear();
  levelMapV2.clear();
  return abReasons;
};

注入Remark

/**
 * injectOneLevelRemark
 * @param abReasons
 * @param key
 * @param oneLevelRemark
 */
export const injectOneLevelRemark = (
  abReasons: Todo.AbnormalReason[] | undefined,
  key: string,
  oneLevelRemark: string | undefined,
) => {
  if (abReasons && oneLevelRemark && key) {
    for (var i = 0; i < abReasons?.length; i++) {
      if (abReasons[i]?.oneLevel === key) {
        abReasons[i].oneLevelRemark = oneLevelRemark;
        break;
      }
    }
  }
  console.log('abReasons=====>', abReasons);
  return abReasons;
};

监听触发函数

  const changeReasons = (
    values: Dict.DictionaryItem[] | Dict.DictionaryItem[][],
  ) => {

    const abReasons: Todo.AbnormalReason[]  = dictToAbReasons(values);

    formRef.current?.setFieldValue(
        ['review', 'abnormalReasons'],
        abReasons
    );

    let flag = containsKey(abReasons,'backOneLevelRemark');
    setOneLevelRemarkSwitch(flag);
    if (!flag){
      initOneLevelRemark();
    }
  };
  
  const handleSubmit = async (value: A.Xxx) => {
    injectOneLevelRemark(value.review?.abnormalReasons, 'backOneLevelRemark', value?.review?.abReasonsOneLevelRemark);
    // ...
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值