2017-02-09 52 views
0

我在處理JS中的一些數據時感覺有些困難,我從API輸出數據。對分層嵌套數據進行迭代並從中構建html

後端輸出的是可以嵌套到第N級別的類別列表。

我試圖做的是爲他們生成一個不錯的嵌套結構,使他們所代表的JSON結構,但在DOM:

<div> 
    Women's Fashion 
    <div> 
     Women's Clothes 
     <div>Dresses</div> 
     <div>Watches</div> 
     <div>Etc.</div> 
    </div> 
    <div> 
     Watches 
    </div> 
    <div> 
     Jewellery 
     <div>Swarowski</div> 
     <div>Other</div> 
    </div> 
</div> 

什麼是一個好辦法,我實現這個結構呢?

以下是我輸出的數據的示例。這裏的關鍵是每個類別可以有M個子類別,而結束深度實際上並不受限制。

{ 
    "results": [ 
     { 
      "id": 1, 
      "name": "Women's Fashion", 
      "hashtag": "#womensfashion", 
      "parent_id": null, 
      "parents_list": [], 
      "product_count": 9466, 
      "subcategories": [ 
       { 
        "id": 2, 
        "name": "Womens Clothes", 
        "hashtag": "#womensclothes", 
        "parent_id": 1, 
        "parents_list": [ 
         1 
        ], 
        "product_count": 2940, 
        "subcategories": [ 
         { 
          "id": 3, 
          "name": "Dresses", 
          "hashtag": "#dresses", 
          "parent_id": 2, 
          "parents_list": [ 
           2, 
           1 
          ], 
          "product_count": null, 
          "subcategories": [] 
         }, 
         { 
          "id": 4, 
          "name": "Tops", 
          "hashtag": "#womenstops", 
          "parent_id": 2, 
          "parents_list": [ 
           2, 
           1 
          ], 
          "product_count": null, 
          "subcategories": [] 
         }, 
         { 
          "id": 5, 
          "name": "Outwear", 
          "hashtag": "#womensoutwear", 
          "parent_id": 2, 
          "parents_list": [ 
           2, 
           1 
          ], 
          "product_count": null, 
          "subcategories": [] 
         }, 
         { 
          "id": 6, 
          "name": "Shirts", 
          "hashtag": "#womensshirts", 
          "parent_id": 2, 
          "parents_list": [ 
           2, 
           1 
          ], 
          "product_count": null, 
          "subcategories": [] 
         }, 
         { 
          "id": 7, 
          "name": "Pants and Shorts", 
          "hashtag": "#womenspantsandshorts", 
          "parent_id": 2, 
          "parents_list": [ 
           2, 
           1 
          ], 
          "product_count": null, 
          "subcategories": [] 
         }, 
         { 
          "id": 8, 
          "name": "Skirts", 
          "hashtag": "#skirts", 
          "parent_id": 2, 
          "parents_list": [ 
           2, 
           1 
          ], 
          "product_count": null, 
          "subcategories": [] 
         }, 
         { 
          "id": 9, 
          "name": "Jeans", 
          "hashtag": "#womensjeans", 
          "parent_id": 2, 
          "parents_list": [ 
           2, 
           1 
          ], 
          "product_count": null, 
          "subcategories": [] 
         }, 
         { 
          "id": 10, 
          "name": "Lingerie and Nightweare", 
          "hashtag": "#lingerieandnightweare", 
          "parent_id": 2, 
          "parents_list": [ 
           2, 
           1 
          ], 
          "product_count": null, 
          "subcategories": [] 
         }, 
         { 
          "id": 12, 
          "name": "Muslimawear", 
          "hashtag": "#womensmuslimawear", 
          "parent_id": 2, 
          "parents_list": [ 
           2, 
           1 
          ], 
          "product_count": null, 
          "subcategories": [] 
         }, 
         { 
          "id": 109, 
          "name": "Other Womensclothes", 
          "hashtag": "#otherwomensclothes", 
          "parent_id": 2, 
          "parents_list": [ 
           2, 
           1 
          ], 
          "product_count": null, 
          "subcategories": [] 
         }, 
         { 
          "id": 135, 
          "name": "Sweaters and Jackets", 
          "hashtag": "#womenssweatersandjackets", 
          "parent_id": 2, 
          "parents_list": [ 
           2, 
           1 
          ], 
          "product_count": null, 
          "subcategories": [] 
         } 
        ] 
       }, 
       { 
        "id": 15, 
        "name": "Bags, Purses and Wallets", 
        "hashtag": "#womensbags", 
        "parent_id": 1, 
        "parents_list": [ 
         1 
        ], 
        "product_count": 1626, 
        "subcategories": [] 
       }, 
       { 
        "id": 16, 
        "name": "Shoes", 
        "hashtag": "#womensshoes", 
        "parent_id": 1, 
        "parents_list": [ 
         1 
        ], 
        "product_count": 811, 
        "subcategories": [] 
       }, 
       { 
        "id": 19, 
        "name": "Watches", 
        "hashtag": "#womenswatches", 
        "parent_id": 1, 
        "parents_list": [ 
         1 
        ], 
        "product_count": 513, 
        "subcategories": [] 
       }, 
       { 
        "id": 17, 
        "name": "Eyewear", 
        "hashtag": "#womenseyewear", 
        "parent_id": 1, 
        "parents_list": [ 
         1 
        ], 
        "product_count": 145, 
        "subcategories": [] 
       }, 
       { 
        "id": 18, 
        "name": "Jewellery", 
        "hashtag": "#womensjewellery", 
        "parent_id": 1, 
        "parents_list": [ 
         1 
        ], 
        "product_count": 289, 
        "subcategories": [] 
       }, 
       { 
        "id": 110, 
        "name": "Other Womensfashion", 
        "hashtag": "#otherwomensfashion", 
        "parent_id": 1, 
        "parents_list": [ 
         1 
        ], 
        "product_count": 129, 
        "subcategories": [] 
       } 
      ] 
     } 
    ] 
} 

我在想我需要做的是聲明一個函數,它遍歷一個層次並返回所有內容。像

process_category(category) 
{ 
    let html = []; 
    for(var i = 0; i < category.length; i++) 
    { 
     let nested_html = null; 
     if(i.subcategories.length > 0) 
     { 
      nested_html = process_category(i.subcategories); 
     } 
     let new_html = [ 
      <ListItem 
        primaryText={i.name} 
        onTouchTap={this.click_category.bind(this, i.id)} 
        nestedItems={[nested_html]} 
      /> 
     ]; 
     html = [...html, ...new_html]; 
    } 
    return(html); 
} 

編輯: 倍感stupud不實現的JavaScript /每個作品(正在寫一個python for x in categories: print x.name

固定代碼的作品,但我不知道如何得到優化:

process_category(category) 
{ 
    let html = []; 
    for(var i in category) 
    { 
     let nested_html = null; 
     if(category[i].subcategories.length > 0) 
     { 
      nested_html = this.process_category(category[i].subcategories); 
     } 
     let new_html = [ 
      <ListItem 
        primaryText={category[i].name} 
        // onTouchTap={this.click_category.bind(this, category[i].id)} 
        nestedItems={nested_html} 
      /> 
     ]; 
     html = [...html, ...new_html]; 
    } 
    return(html); 
} 
+0

你嘗試過什麼?請編輯您的問題以包含您迄今爲止的代碼。 –

+0

對不起,我注意到這是非常不完整的,我剛剛編輯了一些我嘗試過的東西。 –

回答

0

我會建議遞歸:

function generateDom(obj) { 
    var node = document.createElement("div"); 
    var textnode = document.createTextNode(obj.name); 
    node.appendChild(textnode);   
    for (var i in obj.subcategories) { 
    var subcategory = obj.subcategories[i]; 
    node.append(generateDom(subcategory)); 
    } 
    return node; 
} 

工作示例:https://jsfiddle.net/mspinks/fdk2m2ua/

0

下面是一個基於reactjs小提琴,可能讓你在正確的方向:https://jsfiddle.net/giladaya/yo4xa3z1/4/

要注意的主要事情是使用遞歸的組件:

const Item = function(props) { 
    let { data } = props 
    let children 
    if (data.subcategories.length > 0) { 
    children = (
     <div className={`level-${props.level}`}> 
     {data.subcategories.map((item, idx) => 
      <Item data={item} level={props.level+1} key={`item-${idx}`}/> 
     )} 
     </div> 
    ) 
    } else { 
    children = null 
    } 
    return (
    <div> 
     {data.name} 
     {children} 
    </div> 
) 
}