如果我的术语不正确,我道歉 - 这绝对不是我的专业领域。
我希望从json文件中创建一个<select>
列表,并用密钥对<optgroup>
中的条目进行分组。我已经成功地列出了select中的所有条目,但是不知道如何在其键下循环并嵌套项目。
我的JSON看起来像这样:
[
{
"Type" : "Overdrive",
"Brand" : "Chase Bliss",
"Name" : "Brothers",
"Width" : 2.75,
"Height" : 4.77,
"Image" : "public/images/pedals/chasebliss-brothers.png"
}
]
以下是我如何呈现<select>
:
window.RenderPedals = function(pedals){
for(var i in pedals) {
var $pedal = $("<option>"+ pedals[i].Brand + " " + pedals[i].Name +"</option>").attr('id', pedals[i].Name.toLowerCase().replace(/\s+/g, "-").replace(/'/g, ''));
$pedal.data('width', pedals[i].Width);
$pedal.data('height', pedals[i].Height);
$pedal.data('height', pedals[i].Height);
$pedal.data('image', pedals[i].Image);
$pedal.appendTo('.pedal-list');
}
}
我正在寻找的是这个标记:
<select>
<optgroup label="Chase Bliss">
<option data-width="..." data-height="..." data-image="...">Chase Bliss Brothers</option>
</optgroup>
</select>
有人能指出我正确的方向吗?
答案 0 :(得分:0)
您可以使用对象解构来获取当前对象的属性,而不使用for..in
循环,创建<optgroup>
元素并将label
属性设置为"Brand"
,附加<option>
} <optgroup>
,将<optgroup>
追加到<select>
。检查<optgroup>
属性设置为label
的{{1}}元素是否存在,如果Brand
,则将true
追加到<option>
,否则追加新<optgroup>
元素到<optgroup>
,<select>
设置为新的html
元素。
<option>
var data = [{
"Type": "Overdrive",
"Brand": "Chase Bliss",
"Name": "Brothers",
"Width": 2.75,
"Height": 4.77,
"Image": "public/images/pedals/chasebliss-brothers.png"
}
, {
"Type": "Underdrive",
"Brand": "Bliss Chase",
"Name": "Sisters",
"Width": 5.72,
"Height": 7.74,
"Image": "public/images/pedals/chasebliss-sisters.png"
}
, {
"Type": "Throughdrive",
"Brand": "Bliss Chase",
"Name": "Cousins",
"Width": 2.75,
"Height": 4.74,
"Image": "public/images/pedals/chasebliss-cousins.png"
}
];
window.RenderPedals = function(pedals) {
var {Type, Brand, Name, Width, Height, Image} = pedals;
var option = $("<option>", {
text: `${Brand} ${Name}`,
id: Name.toLowerCase()
.replace(/(\s+)|(['"])/g, (m, p1, p2) => p1 ? "-" : ""),
data: {
width: Width,
height: Height,
image: Image
}
});
if ($("optgroup").is(`[label="${Brand}"]`)) {
$(`optgroup[label="${Brand}"]`).append(option);
} else {
$("<optgroup>", {
label: Brand,
html: option
}).appendTo(".pedal-list");
}
}
data.forEach(RenderPedals);
答案 1 :(得分:0)
如果您的数据结构与HTML匹配,那么推理起来会容易得多。
给定的
[
{
"Type" : "Overdrive",
"Brand" : "Chase Bliss",
"Name" : "Brothers",
"Width" : 2.75,
"Height" : 4.77,
"Image" : "public/images/pedals/chasebliss-brothers.png"
}
]
虽然你想要结构
<select>
<optgroup label="Chase Bliss">
<option data-width="..." data-height="..." data-image="...">Chase Bliss Brothers</option>
</optgroup>
</select>
不要尝试从JSON转换为HTML,而是创建一个与HTML匹配的新数据结构。如果数据结构与HTML结构匹配,则呈现它的逻辑将更容易。
以下情况会很好..
[
{
brandName: "Chase Bliss",
items: [ { name: "Brothers" /* width, height, etc */ } ]
}
]
您可以编写一个reduce函数来进行此转换:
let optionGroups = pedals.reduce((optionGroups, pedal) => {
let optionGroup = optionGroups.find(group => pedal.Brand === group.brandName) || {}
if (!optionGroup.brandName) {
optionGroup.brandName = pedal.Brand
optionGroup.items = []
optionGroups.push(optionGroup)
}
optionGroup.items.push(pedal)
return optionGroups
}, [])
然后,渲染函数可以只映射外部组,然后映射内部项。
window.renderPedals = (optionGroups) => {
optionGroups.map((group) => {
let $optgroup = $("<optgroup>", {
label: group.brandName
});
group.items.map((pedal) => {
let {Type, Brand, Name, Width, Height, Image} = pedal;
let $pedal = $("<option>", {
text: `${Brand} ${Name}`,
id: `${Name.toLowerCase().replace(/\s+/g, "-").replace(/'/g, '')}`,
data: {
width: Width,
height: Height,
image: Image
},
appendTo: $optgroup
});
})
$optgroup.appendTo(".pedal-list");
})
}