2017-03-01 30 views
7

如果我的術語不正確,我很抱歉 - 這絕對不是我的專業領域。列出按鍵分組的數組內容

我期待從json文件中創建一個<select>列表,並通過鍵將<optgroup>s中的條目分組。我已經成功地列出了選擇中的所有條目,但不知道如何循環並嵌套項目。

我的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> 

能任何人都指向正確的方向?

+1

如果'pedals'是一個數組,你應該看看[這個問題,它的答案(http://stackoverflow.com/questions/500504/why-is-using - 對於功能於與陣列迭代-A-壞主意?RQ = 1)。 –

回答

0

你可以使用對象解構當前對象的屬性,沒有for..in循環,創建一個<optgroup>元素與label屬性設置爲"Brand",追加<option><optgroup>,追加<optgroup><select>。檢查是否存在具有label屬性設置爲Brand<optgroup>元素,如果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);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> 
 
</script> 
 
<select class="pedal-list"></select>

+0

這不會錯過'分組'部分嗎?即陣列中的所有條目將列在第一個品牌下。 – bsyk

+0

@bsyk不確定你的意思?問題中只有一個對象出現在數組中。 OP可以使用'data.forEach(RenderPedals)' – guest271314

+0

我假設問題中的數據被簡化爲單個條目,並且在真實應用程序中會有更多條目,否則分組列表框的要點是什麼。 嘗試使用不同的品牌值向陣列中添加更多條目。 – bsyk

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 */ } ] 
    } 
] 

你可以寫一個減少功能,使這一轉變:

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"); 
    }) 
} 

https://jsfiddle.net/f4x9vk0f/2/