如何将对象值绑定到含重复data-param-name属性的HTML元素?
问题:重复
data-param-name属性的元素绑定数据失败 需求说明
- 有一批带
data-param-name属性的div元素,部分属性值重复 - 需要把指定对象的对应值绑定到元素的innerHTML,重复属性需对应数组中的不同项(比如两个
data.user.name分别对应数组第一个和第二个对象的name)
示例数据
const data = { user: [ {name: 'saeed', job: ['engineer']}, {name: 'ali', job: ['employee']} ], type: 'x' }
目标HTML元素
[ <div data-param-name="data.user.name"></div>, <!-- 期望innerHTML: 'saeed' --> <div data-param-name="data.type"></div>, <!-- 期望innerHTML: 'x' --> <div data-param-name="data.user.name"></div>, <!-- 期望innerHTML: 'ali' --> <div data-param-name="data.user.job"></div>, <!-- 期望innerHTML: 'engineer' --> ]
我的错误代码
for (const element of elementCollection) { const dataTitle = element.getAttribute('data-title'); const dataParamName = element.getAttribute('data-param-name'); if (dataParamName) { const splitArray = dataParamName.toLowerCase().split('.'); const result = splitArray.reduce((acc: any, cur: any) => { if (Array.isArray(acc)) { return acc[arr[dataParamName]]?.[cur]; } return acc?.[cur] || ''; }, fields); if (result) { if (typeof result === 'number') { element.innerHTML = `${zeroSeparator(result)}`; } else { element.innerHTML = result ? toPersianDigit(result) : ''; } } } }
问题分析与修复
你的代码存在几个关键问题:
- 数组索引逻辑错误:遍历到数组类型的
acc时,使用了未定义的arr变量,且没有针对重复属性做计数,无法区分多个相同属性对应数组的不同项。 - 初始值错误:
reduce的初始值是fields,但实际数据对象是data,导致路径遍历起点错误。 - 路径转小写问题:
dataParamName.toLowerCase()会改变属性名大小写,若数据对象属性有大小写区分,会导致取值失败。
修复后的代码
// 统计每个data-param-name的出现次数,用于匹配数组项索引 const paramCounter = {}; for (const element of elementCollection) { const dataParamName = element.getAttribute('data-param-name'); if (!dataParamName) continue; // 初始化当前属性的计数器 const paramKey = dataParamName; paramCounter[paramKey] = (paramCounter[paramKey] || 0); // 拆分属性路径,保留原大小写 const splitArray = paramKey.split('.'); let result = data; // 从根数据对象开始遍历 for (const segment of splitArray) { if (result === undefined) break; // 遇到数组时,用当前计数器值作为索引 if (Array.isArray(result)) { result = result[paramCounter[paramKey]]; } else { result = result[segment]; } } // 处理结果并赋值到innerHTML if (result !== undefined) { if (typeof result === 'number') { element.innerHTML = `${zeroSeparator(result)}`; } else { // 若结果是数组(比如job字段),取第一个元素展示 const displayValue = Array.isArray(result) ? result[0] : result; element.innerHTML = displayValue ? toPersianDigit(displayValue) : ''; } } else { element.innerHTML = ''; } // 计数器递增,下一个相同属性的元素将匹配数组下一项 paramCounter[paramKey]++; }
修复要点
- 添加
paramCounter:统计每个属性的出现次数,解决重复属性对应数组不同项的问题。 - 修正遍历起点:将
reduce的初始值改为实际数据对象data。 - 保留属性名原大小写:去掉
toLowerCase(),避免属性名匹配失败。 - 优化数组处理:遇到数组时用计数器值作为索引,同时处理
job这类数组型字段(取第一个元素)。 - 完善边界处理:当结果为
undefined时,设置空innerHTML,避免页面报错。
内容的提问来源于stack exchange,提问作者Saeed Hemmati
相关产品推荐
相关产品推荐

