【问题标题】:Making json conform to Bootstrap Treeview format使 json 符合 Bootstrap Treeview 格式
【发布时间】:2024-05-21 09:20:02
【问题描述】:

我正在尝试找出将一些 JSON 数据转换为bootstrap-treeview 请求格式的最佳方法。我最初的想法是创建某种递归函数来遍历和修改所有内容,但我在实现这一点时遇到了一些真正的困难。任何建议将不胜感激!

这里是我的服务返回的数据的控制台日志:

Object
  England: Object
    London: Object
      Bayerische Staatsbibliothek: Object
        Cod. arab. 1251: Array[1]
          0: Object
            key1: "adflkjadf",
            key2: "adflkjadfk",
            key3: "adlkfjadf",
            __proto__: Object
            length: 1
          text: "Cod. arab. 1251"
          __proto__: Array[0]
        Cod. arab. 1252: Array[1]
        Cod. arab. 1253: Array[1]
        Cod. arab. 1254: Array[1]
        Cod. arab. 1255: Array[1]
        Cod. arab. 1256: Array[1]
        Cod. arab. 1257: Array[1]
        Cod. arab. 1258: Array[1]
        Cod. arab. 1259: Array[1]
        Cod. arab. 1260: Array[1]
  Germany: Object
    Munich: Object
      Bayerische Staatsbibliothek: Object
        Cod. arab. 1251: Array[1]
          0: Object
            key1: "adflkjadf",
            key2: "adflkjadfk",
            key3: "adlkfjadf",
            __proto__: Object
            length: 1
          text: "Cod. arab. 1251"
          __proto__: Array[0]
        Cod. arab. 1252: Array[1]
        Cod. arab. 1253: Array[1]
        Cod. arab. 1254: Array[1]
        Cod. arab. 1255: Array[1]
        Cod. arab. 1256: Array[1]
        Cod. arab. 1257: Array[1]
        Cod. arab. 1258: Array[1]
        Cod. arab. 1259: Array[1]
        Cod. arab. 1260: Array[1]

这是 boostrap-treeview 需要的格式:

var tree = [
  {
    text: "Parent 1",
    nodes: [
      {
        text: "Child 1",
        nodes: [
          {
            text: "Grandchild 1"
          },
          {
            text: "Grandchild 2"
          }
        ]
      },
      {
        text: "Child 2"
      }
    ]
  },
  {
    text: "Parent 2"
  },
  {
    text: "Parent 3"
  },
  {
    text: "Parent 4"
  },
  {
    text: "Parent 5"
  }
];

这是我尝试使用递归函数来完成此操作:

function format_for_treeview(node) {
  for (var key in node) {
    // skip loop if the property is from prototype
    if (!node.hasOwnProperty(key)) continue;

    if (typeof node === 'object') {
      format_for_treeview(node[key]);
      if (Array.isArray(node)) {
        node[key]['text'] = node[key]['bibliography_text'];
      } else {
        node[key]['text'] = key;
      }
    }
  }  
}

【问题讨论】:

    标签: javascript json recursion treeview bootstrap-treeview


    【解决方案1】:

    following link 的帮助下,我发现d3 的nest() 函数几乎完全符合我的需要。但是,我确实必须分叉 d3.js 文件并在 nest()->entries() 映射函数中重命名“键”和“值”键名。

    此外,我修改了服务以返回一个对象数组,而不是尝试在服务内进行分组。

      var withText = jsondata.map(function(i) {
        i['text'] = i['bibliography_text'];
        return i;
      });
    
      var nestedData = d3.nest()
        .key(function(d) { return d.country; })
        .key(function(d) { return d.city; })
        .entries(withText);
    

    结果输出为我提供了一个与上面列出的 var tree = [...] 完全相同的数组。

    【讨论】:

      【解决方案2】:

      如果您需要 bootstrap treeview 并希望将任意 JSON 数据解析为其格式。你可以使用这个递归的function。我只是对您的原始代码进行了一些更改。

      function format_for_treeview(node) {
        for (var key in node) {
          // skip loop if the property is from prototype
          if (!node.hasOwnProperty(key)) continue;
      
          if (typeof node === 'object') {
            format_for_treeview(node[key]);
            if (Array.isArray(node)) {
              node[key]['text'] = node[key]['bibliography_text'];
            } else {
              node[key]['text'] = key;
            }
          }
        }  
      }
      

      改变它会像你预期的那样工作。 (见下面的代码sn-p。)

      function format_for_treeview(data, arr) {
        for (var key in data) {
           if(Array.isArray(data[key]) || data[key].toString() === "[object Object]") {
              // when data[key] is an array or object
              var nodes = [];
              var completedNodes = completeNodes(data[key], nodes);
              arr.push({ text: key, nodes: completedNodes });
           } else {
              // when data[key] is just strings or integer values
              arr.push({ text: key + " : " + data[key] });
           }
        }  
        return arr;
      }
      

      var data = {
        "title": "Person",
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "age": {
            "description": "Age in years",
            "type": "integer",
            "minimum": 0
          }
        },
        "required": ["firstName", "lastName"]
      };
      
      $(document).ready(function() {
        function format_for_treeview(data, arr) {
          for (var key in data) {
            if (Array.isArray(data[key]) || data[key].toString() === "[object Object]") {
              // when data[key] is an array or object
              var nodes = [];
              var completedNodes = format_for_treeview(data[key], nodes);
              arr.push({
                text: key,
                nodes: completedNodes
              });
            } else {
              // when data[key] is just strings or integer values
              arr.push({
                text: key + " : " + data[key]
              });
            }
          }
          return arr;
        }
      
      
        $("#my-treeview").treeview({
          color: "#428bca",
          expandIcon: "glyphicon glyphicon-stop",
          collapseIcon: "glyphicon glyphicon-unchecked",
          showTags: true,
          data: format_for_treeview(data, [])
        });
      
      });
      <link href="https://jonmiles.github.io/bootstrap-treeview/bower_components/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
      <script src="https://jonmiles.github.io/bootstrap-treeview/js/bootstrap-treeview.js"></script>
      <div id="my-treeview"></div>

      您可以自定义 push 部分,通过在它们之间插入 HTML 字符串来使“key : value”更显眼,如下所示。

      arr.push({ text: "<span class="key-stub"> + key + "</span>", nodes: completedNodes });
      

      就个人而言,如果您只需要将JSON 转换为树视图的功能,则不必为此而苦恼。只需考虑使用this one. 无需转换。

      【讨论】: