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

使用D3构建数据驱动侧边导航遇报错:无法处理嵌套数据

解决D3数据驱动侧边导航的嵌套数据问题

错误原因分析

你遇到的Uncaught TypeError: undefined is not iterable错误主要来自三个问题:

  • 拼写错误:数据里的嵌套字段是hasPages,但代码里写成了d.hasItems,导致取到undefined
  • 逻辑错误:给所有侧边栏项都添加了下拉容器,包括没有子页面的Notifications和Messages
  • 结构错误:下拉菜单(ul.sidebar-dropdown)应该作为li.sidebar-item的子元素,而不是嵌套在<a>标签里

修正后的完整代码

const sidenavData = [
    { 'name': 'Header name 1', 'type': 'header' },
    { 'name': 'Menu item 1', 'type': 'item', 'hasPages': [
            { 'name': 'Page 1' },
            { 'name': 'Page 2' },
        ]
    },
    { 'name': 'Menu item 2', 'type': 'item', 'hasPages': [
            { 'name': 'Report 1' },
            { 'name': 'Report 2' },
            { 'name': 'Report 3' },
        ]
    },
    { 'name': 'Header name 2', 'type': 'header' },
    { 'name': 'Notifications', 'type': 'item' },
    { 'name': 'Messages', 'type': 'item' },
];

// 选择顶层导航容器
var nav = d3.select('ul.sidebar-nav');

// 创建顶层li元素(包含header和item)
const topLevelItems = nav
    .selectAll('li')
    .data(sidenavData)
    .enter()
    .append('li')
    .attr('class', d => d.type === 'header' ? 'sidebar-header' : 'sidebar-item');

// 处理header的文本
topLevelItems.filter(d => d.type === 'header')
    .text(d => d.name);

// 处理普通item:添加a标签
const sidebarItems = topLevelItems.filter(d => d.type === 'item')
    .append('a')
    .attr('class', 'sidebar-link')
    .text(d => d.name);

// 处理有子页面的item:添加下拉菜单
sidebarItems.filter(d => d.hasPages)
    // 回到父元素li,添加下拉ul
    .each(function(d) {
        d3.select(this.parentNode)
            .append('ul')
            .attr('class', 'sidebar-dropdown')
            .selectAll('li')
            .data(d.hasPages)
            .enter()
            .append('li')
            .attr('class', 'sidebar-item')
            .append('a')
            .attr('class', 'sidebar-link')
            .text(page => page.name);
    });

关键修正点说明

  • 字段名修正:把d.hasItems改为d.hasPages,匹配数据结构
  • 条件渲染下拉:通过filter(d => d.hasPages)只给有子页面的项添加下拉容器
  • 修正DOM结构:使用this.parentNode回到父级li元素,将下拉ul作为li的子元素,符合期望的HTML结构
  • 分层处理元素:拆分顶层元素、header、普通item、下拉菜单的创建逻辑,让代码更清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 07:27:09