如何从 JavaScript 数据结构生成 HTML 列表结构?

How can I produce an HTML list structure from JavaScript data structure?

我需要遍历这个数据结构来呈现一组列表。对于嵌套数据与父级结构相同的结构,这没有问题 - 但这里所有模型都不同。将有一个列表,其中每个项目包含此结构中每个级别的列表。像这样:

想要的结果:

未选择

| Countries | Provinces | Cities      | <--- Top ul
---------------------------------------
|-China     |           |             | <--- Sub uls
|-Denmark   |           |             |

已选择

| Countries | Provinces | Cities      |
---------------------------------------
|-China   X |-Matjii X  |- Go Neng    |
|-Denmark   |-Pausiu    |- Tsau Pei X |

X代表一个选择的选项。如果选择了一个项目,则只有它的信息应该显示在后续列表中。正如您在上面看到的,由于选择了 China,因此以下列表没有显示来自 Denmark 的数据。

数据结构:

{
  countries: {
    china: {
      name: "China",
      provinces: {
        matjii: {
          name: "Matjii",
          cities: {
            goneng: {
              name: "Go Neng"
            },
            tsauPei: {
              name: "Tsau Pei"
            }
          }
        },
        pausiu: {
          name: "Pausiu",
          cities: {...}
        }
      }
    },
    denmark: {
      name: "Denmark",
      counties: {
        borjskada: {
          name: "Borjskada",
          towns: {
            fjollmaska: {
              name: "Fjollmaska"
            }
          }
        },
        larvmauda: {
          name: "Larvmauda",
          towns: {
            tarnaby: {
              name: "Taernaby"
            }
          }
        }
      }
    }
  }
}

我尝试过两种不同的递归方法,但让我停滞不前的是,我总是无法预料下一个级别可能被称为什么(城市、城镇或 matjii)。

我是否遗漏了一些简单明显的解决方案?伪代码很好,我正在寻找一个通用的方法。

基本上,我认为关键在于从后端或前端 (js) 规范化数据。

在此回复中,我假设您别无选择,只能从前端进行。

每个国家/地区对其地理位置都有不同的命名约定,例如。有人将其命名为市、县、镇、村等。

尽管命名不同,但它们都遵循树状层次结构。因此,这是您的攻角。根据层级对它们进行规范化。

以下示例代码将按层次打印出您的示例数据。它们的水平与缩进量形成对比。复制并粘贴以下代码,然后 运行 将其粘贴到您的浏览器控制台中。

数据:

var data = {
  countries: {
    china: {
      name: "China",
      provinces: {
        matjii: {
          name: "Matjii",
          cities: {
            goneng: {
              name: "Go Neng"
            },
            tsauPei: {
              name: "Tsau Pei"
            }
          }
        },
        pausiu: {
          name: "Pausiu",
        }
      }
    },
    denmark: {
      name: "Denmark",
      counties: {
        borjskada: {
          name: "Borjskada",
          towns: {
            fjollmaska: {
              name: "Fjollmaska"
            }
          }
        },
        larvmauda: {
          name: "Larvmauda",
          towns: {
            tarnaby: {
              name: "Taernaby"
            }
          }
        }
      }
    }
  }
}

函数:

function traverseDataStructure(rootNode, nodeLevel){

    if(!rootNode) return;

    if(nodeLevel > 3) return;  //just a secondary protection for infinite recursion

    if(!nodeLevel)
        nodeLevel = 0;

    var indentationForPrinting = '';
    for(var i=0;i<nodeLevel;i++){
        indentationForPrinting += '    ';
    }

    console.log(indentationForPrinting + 'Traversing level ' + nodeLevel);

    for(var prop in rootNode){

        //prop may either by countries (level 0) or provinces (level 1) or counties (level 1) or cities (level 2) or towns (level 2)
        var regionType = prop;
        var regionList = getRegionList(rootNode[prop]);
        console.log(indentationForPrinting + 'regionType: ' + regionType);
        console.log(indentationForPrinting + 'regionList: ' + regionList);

        if(regionList.length <= 0) return;

        //then iterate the list of regions
        for(var i=0;i<regionList.length; i++){

            for(var subRegion in regionList[i]){
                if (subRegion == 'name'){
                    var regionName = regionList[i][subRegion];
                    console.log(indentationForPrinting + 'regionName: ' + regionName);
                } else {
                    traverseDataStructure({subRegion: regionList[i][subRegion]}, nodeLevel+1);
                }
            }
        }
    }
}

function getRegionList(obj){
    var list = [];
    for(var location in obj){
        list.push(obj[location]);
    }
    return list;
}

运行它:

traverseDataStructure(data);

预期输出:

希望这可以为您提供解决问题的替代方法