【问题标题】:Nested JSON dictionary where last level can be standard element or another dict嵌套 JSON 字典,其中最后一级可以是标准元素或另一个字典
【发布时间】:2017-11-24 08:01:13
【问题描述】:

所以我有一个 JSON 字典,我使用 Knockout js 访问它。该对象的结构是一个嵌套字典,但最后一级包含一些标准 JSON key:val 对和一些字典 key:{key1:val1, key2:val2},我正在动态访问它们以创建嵌套表。我知道这听起来很乱,但我需要这样做(可能不会,如果你有更好的想法 lmk)

var dummy = {
    "Dummy Data": {
        "dummy1":{
            "dummy1.1":"val1",
            "dummy1.2":"val2",
            "dummy1.3":"val3"
        },
        "dummy2":{
            "dummy2.1":"val1",
            "dummy2.2":{
                "dummy2.2.1":"val2.1",
                "dummy2.2.2":"val2.2"
            },
            "dummy2.3":"val3"
        },
        "dummy3":{
            "dummy3.1":"val1",
            "dummy3.2":"val2"
        }
    }
}

function mapDictionaryToArray(dictionary) {
	var result = [];
	for (var key in dictionary) {
		if (dictionary.hasOwnProperty(key)) {
		    result.push({ key: key, value: dictionary[key] }); 
		}  
	}
	return result;
}

ko.applyBindings(dummy);
table {
	font-family: arial, sans-serif;
	border-collapse: collapse;
	width: 100%;
}

td, th {
	border: 1px solid #dddddd;
	text-align: left;
	padding: 8px;
}
<!DOCTYPE html>
<html>
<body>
  <table>
    <tr data-bind="foreach: mapDictionaryToArray(value)">
      <th data-bind="text: key"></th>
    </tr>
    <tr data-bind="foreach: mapDictionaryToArray(value)">
      <td>
        <table>
          <tr data-bind="foreach: mapDictionaryToArray(value)">
            <td data-bind="text: key"></td>
          </tr>
          <tr data-bind="foreach: mapDictionaryToArray(value)">
            <td data-bind="text: value"></td>
          </tr> 									
        </table>
      </td>
    </tr>
  </table>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js" crossorigin="anonymous"></script>
</body>
</html>

目前带有字典而不是直接值的表格元素只是说[object Object],但我想要一种方法来显示另一个表格/分解单元格并适合其余部分

【问题讨论】:

    标签: javascript html json dictionary knockout.js


    【解决方案1】:

    我不完全确定您想要的结果是什么,但我希望这会有所帮助:

    要创建嵌套结构,您可以嵌套template 绑定。这允许您在视图中创建递归模式。

    如果您的数据结构已经定义,这会有所帮助,因此我也将 mapDictionaryToArray 方法设为递归。 (这确保您不必在绑定处理程序中调用该函数)。

    有一个getTemplate 方法可以确定value 是“叶子”(树中的最后一个)还是分支(需要另一个表)。

    var dummy = {
      "Dummy Data": {
        "dummy1": {
          "dummy1.1": "val1",
          "dummy1.2": "val2",
          "dummy1.3": "val3"
        },
        "dummy2": {
          "dummy2.1": "val1",
          "dummy2.2": {
            "dummy2.2.1": "val2.1",
            "dummy2.2.2": "val2.2"
          },
          "dummy2.3": "val3"
        },
        "dummy3": {
          "dummy3.1": "val1",
          "dummy3.2": "val2"
        }
      }
    }
    
    function mapDictionaryToArray(dictionary) {
      var result = [];
      for (var key in dictionary) {
        if (dictionary.hasOwnProperty(key)) {
          var value = dictionary[key];
    
          result.push({
            key: key,
            value: isObj(value) ?
              mapDictionaryToArray(value) :
              value
          });
        }
      }
      return result;
    }
    
    function isObj(data) { 
      return data.toString() === "[object Object]";
    }
    
    function getTemplate(data) {
      return Array.isArray(data) ?
        "t-branch" :
        "t-leaf";
    }
    
    ko.applyBindings({
      firstObj: mapDictionaryToArray(dummy)[0],
      getTemplate: getTemplate
    });
    table {
      font-family: arial, sans-serif;
      border-collapse: collapse;
      width: 100%;
    }
    
    td,
    th {
      border: 1px solid #dddddd;
      text-align: left;
      padding: 8px;
    }
    
    td { 
      vertical-align: top;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js" crossorigin="anonymous"></script>
    
    <div data-bind="template: { data: firstObj, name: 't-table' }"></div>
    
    <script type="text/html" id="t-table">
      <table>
        <thead>
          <th data-bind="text: key"></th>
        </thead>
        <tbody data-bind="template: {
          name: $root.getTemplate(value), 
          data: value 
        }">
        </tbody>
      </table>
    </script>
    
    
    <script type="text/html" id="t-branch">
      <tr data-bind="foreach: $data">
        <td data-bind="template: {
          name: 't-table',
          data: $data 
        }"></td>
      </tr>
    </script>
    
    <script type="text/html" id="t-leaf">
      <tr>
        <td data-bind="text: $data"></td>
      </tr>
    </script>

    【讨论】:

      猜你喜欢
      • 2020-01-01
      • 1970-01-01
      • 2015-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-04
      • 1970-01-01
      相关资源
      最近更新 更多