You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在AngularJS中如何将树形结构JSON渲染为视图树形结构

在AngularJS中展示树形JSON结构的实现方案

嘿,这个问题我刚好处理过!要在AngularJS里展示嵌套的树形JSON,核心思路是用递归指令,因为树形结构是层级嵌套的,递归能完美适配这种场景。下面我给你一步步拆解实现方案:

1. 先统一数据结构

你提供的原始JSON里,节点有两种形式:一种是带键值对的父节点(比如{"Software Products": [...]}),另一种是字符串类型的叶子节点(比如"Try It!")。为了方便递归渲染,我们先把数据转换成统一的节点结构:每个节点包含label(节点名称)和children(子节点数组,空数组表示叶子节点)。

在AngularJS控制器里添加数据转换函数:

angular.module('treeApp', [])
.controller('TreeController', function($scope) {
  // 你的原始树形数据
  $scope.rawTreeData = [
    { "Software Products": [
        { "Programming Languages": [ "Java API", "Python API" ] },
        { "Documentation": [ "Java Docs", "Python Docs", { "HTTP Docs": [ "REST Docs", "SOAP Docs" ] } ] },
        "Try It!"
      ]
    },
    { "Cloud Products": [ "SAAS", "PAAS", "IAAS" ] },
    { "About Us": [
        { "Locations": [
            { "India": [ "Delhi", { "Mumbai": [ "Lower Parel", "Goregaon" ] }, "Bangalore" ] },
            "USA", "Singapore"
          ]
        }
      ]
    }
  ];

  // 递归转换数据结构
  function transformTreeData(data) {
    return data.map(item => {
      if (typeof item === 'string') {
        // 叶子节点:直接返回label+空children
        return { label: item, children: [] };
      } else {
        // 父节点:取键作为label,值作为子节点递归转换
        const key = Object.keys(item)[0];
        return {
          label: key,
          children: transformTreeData(item[key])
        };
      }
    });
  }

  // 转换后的数据,用于渲染
  $scope.treeData = transformTreeData($scope.rawTreeData);
});

2. 定义递归指令

接下来创建一个递归指令treeNode,负责渲染单个节点及其子节点。我们还可以添加折叠/展开的交互功能,提升用户体验:

angular.module('treeApp')
.directive('treeNode', function() {
  return {
    restrict: 'E',
    scope: {
      node: '='
    },
    template: `
      <div class="tree-node">
        <span class="node-label" ng-click="toggleExpand()">
          <!-- 折叠/展开图标 -->
          <span ng-if="node.children.length > 0">
            {{ isExpanded ? '▼' : '▶' }}
          </span>
          {{ node.label }}
        </span>
        <!-- 递归渲染子节点,只有展开状态才显示 -->
        <div class="children" ng-if="node.children.length > 0 && isExpanded">
          <tree-node ng-repeat="child in node.children" node="child"></tree-node>
        </div>
      </div>
    `,
    link: function(scope) {
      // 默认展开所有节点,也可以设为false默认折叠
      scope.isExpanded = true;

      // 切换折叠/展开状态
      scope.toggleExpand = function() {
        scope.isExpanded = !scope.isExpanded;
      };
    }
  };
});

3. 在视图中使用指令

最后在HTML模板里引入指令,传入转换后的树形数据即可:

<!DOCTYPE html>
<html ng-app="treeApp">
<head>
  <style>
    /* 简单的树形样式,可根据需求自定义 */
    .tree-node {
      margin-left: 15px;
    }
    .node-label {
      cursor: pointer;
      user-select: none;
    }
    .children {
      margin-top: 5px;
    }
  </style>
</head>
<body ng-controller="TreeController">
  <h3>产品目录</h3>
  <tree-node ng-repeat="rootNode in treeData" node="rootNode"></tree-node>

  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
  <script src="app.js"></script>
</body>
</html>

关键细节说明

  • 如果不需要折叠/展开功能,直接去掉isExpanded相关逻辑,子节点始终显示即可。
  • 如果你的原始数据已经是{label, children}的统一结构,可以跳过数据转换步骤。
  • 样式部分可以根据自己的需求完全自定义,比如添加图标、调整缩进等。

内容的提问来源于stack exchange,提问作者Piyush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:17:38