0

我有一个动态的表格,就是嵌套的,表格是用来描述桥式龙门吊的。

所以结构看起来像这样:

let equipmentInfo = {   
  bridges:[{
    trolleys:[{
      hoists:[{
      
      }]
    }]
  }] 
}

我为每组桥、小车和起重场设置了一个功能组件。我传递了一个数组,描述了它在树中的位置,例如:

let keyPath = [['arrayLocation', indexOfEntry]] // [['bridge', 1], ['trolley',3], ['hoist', 0]]

我的问题围绕着这个 getObject 函数的使用

const getObject = (object, location) => {
    if(object == undefined) return {}
    if(location.length == 0) return object
    if(location.length == 1) return object[location[0][0]][location[0][1]]
    if(location.length == 2) return object[location[0][0]][location[0][1]][location[1][0]][location[1][1]]
    if(location.length == 3) return object[location[0][0]][location[0][1]][location[1][0]][location[1][1]][location[2][0]][location[2][1]] 
    if(location.length == 4) return object[location[0][0]][location[0][1]][location[1][0]][location[1][1]][location[2][0]][location[2][1]][location[3][0]][location[3][1]] 
    if(location.length == 5) return object[location[0][0]][location[0][1]][location[1][0]][location[1][1]][location[2][0]][location[2][1]][location[3][0]][location[3][1]][location[4][0]][location[4][1]] 
    if(location.length == 6) return object[location[0][0]][location[0][1]][location[1][0]][location[1][1]][location[2][0]][location[2][1]][location[3][0]][location[3][1]][location[4][0]][location[4][1]][location[5][0]][location[5][1]]
    if(location.length == 7) return object[location[0][0]][location[0][1]][location[1][0]][location[1][1]][location[2][0]][location[2][1]][location[3][0]][location[3][1]][location[4][0]][location[4][1]][location[5][0]][location[5][1]][location[6][0]][location[6][1]]
}

它在 handleOnChange 中使用如下:

const handleInputChange = (e, keyPath) => {
    
  const { name, value } = e.target;
  const object = {...equipmentInfo}

  const targetObject = getObject(object, keyPath)
  targetObject[name] = value

  setObject(targetObject, object, keyPath)
    
  setEquipmentInfo(object);
};

有一个更好的方法吗?不仅为了更好的可读性,而且支持 n 数量的分支。

  <BridgeFields 
    keyPath={newKeypath} 
    handleOnChange={handleOnChange}
    equipmentInfo={EquipmentInfo}
    setEquipmentInfo={setEquipentInfo}
    
  />

下面是实现示例:

// inside <BridgeFields/>
getObject(equipmentInfo, keyPath).trolleys.map((trolly, index)) => {

  // add to the keyPath the compenent and its index
  let newKeyPath = [...keyPath, ["trolleys", index]]
  
  // Form fields describing a bridge 
  <Form.Component 
    type='text' 
    name='serialNumber'
    onChange={(e)=>{handleOnChange(e, newKeyPath)}
  />

  // also include its child component fields (hoists, etc) .. like:
  <HoistFields 
    keyPath={newKeypath} 
    handleOnChange={handleOnChange}
    equipmentInfo={EquipmentInfo}
    setEquipmentInfo={setEquipentInfo}
}

这很有效,实际上速度很快,但我希望改进我在这里所做的事情。这个设备信息对象还有更多内容,我想让它变得更好。

我很感激任何建议谢谢!

4

1 回答 1

2

一种可能的解决方案(假设location阵列将具有确切的键,即“桥”、“手推车”、“提升机”)是这样使用Array reduce

const getObj = (obj = equipmentInfo, location = [['bridges', 1], ['trolleys', 0], ['hoists', 0]]) => (
    location.reduce(
        (acc, itm) => ({ ... acc[itm[0]][itm[1]] }), obj || {}
  )
);

解释

  1. 对于location数组中的每个项目,获取道具(由第 0 个索引指示)。
  2. prop 对应的值是一个数组。
  3. 使用location索引 1 处的元素值来识别所需的数组元素(上述步骤 2 中的数组)

抱歉,如果这个解释不太清楚。

验证的代码片段

const equipmentInfo = {
  bridges: [{
    trolleys: [{
      hoists: [{
        k0: 'b0t0h0v0'
      }, {
        k1: 'v1'
      }, {
        k2: 'v2'
      }]
    }, {
      hoists: [{
        k0: 'b0t0h1v0'
      }, {
        k1: 'v1'
      }, {
        k2: 'v2'
      }]
    }, {
      hoists: [{
        k0: 'b0t0h2v0'
      }, {
        k1: 'v1'
      }, {
        k2: 'v2'
      }]
    }, {
      hoists: [{
        k0: 'b0t1h0v0'
      }, {
        k1: 'v1'
      }, {
        k2: 'v2'
      }]
    }, {
      hoists: [{
        k0: 'b0t1h1v0'
      }, {
        k1: 'v1'
      }, {
        k2: 'v2'
      }]
    }, {
      hoists: [{
        k0: 'b0t1h2v0'
      }, {
        k1: 'v1'
      }, {
        k2: 'v2'
      }]
    }]
  }, {
    trolleys: [{
      hoists: [{
        k0: 'b1t0h0v0'
      }, {
        k1: 'v1'
      }, {
        k2: 'v2'
      }]
    }, {
      hoists: [{
        k0: 'b1t0h1v0'
      }, {
        k1: 'v1'
      }, {
        k2: 'v2'
      }]
    }, {
      hoists: [{
        k0: 'b1t0h2v0'
      }, {
        k1: 'v1'
      }, {
        k2: 'v2'
      }]
    }, {
      hoists: [{
        k0: 'b1t1h0v0'
      }, {
        k1: 'v1'
      }, {
        k2: 'v2'
      }]
    }, {
      hoists: [{
        k0: 'b1t1h1v0'
      }, {
        k1: 'v1'
      }, {
        k2: 'v2'
      }]
    }, {
      hoists: [{
        k0: 'b1t1h2v0'
      }, {
        k1: 'v1'
      }, {
        k2: 'v2'
      }]
    }]
  }]
};

const getObj = (obj = equipmentInfo, location = [
  ['bridges', 1],
  ['trolleys', 0],
  ['hoists', 0]
]) => (
  location.reduce(
    (acc, itm) => ({ ...acc[itm[0]][itm[1]]
    }), obj || {}
  )
);


console.log('b 1, t 0, h 0', getObj());
console.log('b 1, t 1, h 0', getObj(equipmentInfo, [
  ['bridges', 1],
  ['trolleys', 1],
  ['hoists', 0]
]));
console.log('b 0, t 1, h 0', getObj(equipmentInfo, [
  ['bridges', 0],
  ['trolleys', 1],
  ['hoists', 0]
]));
console.log('b 0, t 0, h 0', getObj(equipmentInfo, [
  ['bridges', 0],
  ['trolleys', 0],
  ['hoists', 0]
]));

编辑

设置对象代码:

const setObj = (updatedObj, obj = equipmentInfo, location = [
  ['bridges', 1],
  ['trolleys', 0],
  ['hoists', 1]
]) => {
  location.reduce((acc, itm, idx) => {
    const tgtObj = acc[itm[0]][itm[1]];
    if (idx < location.length - 1) return tgtObj;
    acc[itm[0]][itm[1]] = {
      ...tgtObj,
      ...updatedObj
    };
    return null;
  }, obj);
};

let myObj = {
  ...equipmentInfo
};
setObj({
  zztest: 'okay'
}, myObj);
console.log(myObj);
于 2022-01-20T04:51:04.910 回答