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

Angular侧边栏折叠菜单问题:切换菜单时无法自动关闭已展开项

解决Angular侧边栏菜单切换时无法自动关闭已展开菜单的问题

问题分析

你的代码存在数据状态与DOM操作脱节的核心问题:

  • selectMenu方法负责修改菜单的active属性,但该状态未与DOM的展开类(showMenu)绑定
  • showSubmenu方法直接手动切换DOM元素的showMenu类,完全独立于数据状态
  • 点击新菜单时,selectMenu虽将其他菜单的active设为false,但对应的DOM元素showMenu类未被移除,导致旧菜单依然展开

修复方案

改用数据驱动视图的方式,让DOM状态完全由menuSidebar中的active属性控制,移除手动操作DOM的冗余逻辑:

1. 修改HTML模板

移除showSubmenu的点击调用,将showMenu类绑定到item.active:

<div class="sidebar" [class.sidebar-close]="!openSidebar" >
    <div class="logo-details">
        <img src="https://zupimages.net/up/22/42/refj.png" /> 
    </div>
    <ul class="nav-links" id="nav-links" >
      <li *ngFor="let item of menuSidebar" #itemEl [class.showMenu]="item.active">
        <div *ngIf="item.sub_menu.length > 0" class="dropdown-title" (click)="selectMenu(item)">
          <a>
            <i [class]="item.icon"></i>
            <span class="link_name">{{item.link_name}}</span>
          </a>
          <i class='bx bxs-chevron-down arrow'></i>
        </div>
        <ul class="sub-menu" [class.blank]="item.sub_menu.length == 0">
          <li><a class="link_name">{{item.link_name}}</a></li>
          <li *ngFor="let item_sub of item.sub_menu" routerLinkActive="active">
            <a [routerLink]="[item_sub.link]">{{item_sub.link_name}}</a>
          </li>
        </ul>
      </li>
    </ul>
  </div>

2. 简化组件TS代码

删除showSubmenu方法,保留selectMenu即可:

import { Component, OnInit } from '@angular/core';
import { MenuSidebar } from './types/menuSidebar';


@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {

    openSidebar: boolean = true;

    menuSidebar: MenuSidebar[] = [
       {
        link_name: 'Category',
        link: null,
        icon: 'bx bx-collection',
        active: false,
        sub_menu: [
          {
            link_name: 'Portfolio',
            link: '/category/portfolio',
          }, 
          {
            link_name: 'Contact',
            link: '/category/contact',
          }, 
        ]
      },
      {
        link_name: 'Markets',
        link: null,
        icon: 'bx bx-collection',
        active: false,
        sub_menu: [
          {
            link_name: 'Indice',
            link: '/markets/indice',
          }, 
        ]
      },
    ]
  
    constructor() { }
    ngOnInit() {}

    selectMenu(parentMenu: { link_name: string }) : void {
      this.menuSidebar.forEach(menu => {
        if (menu.link_name !== parentMenu.link_name) {
          menu.active = false;
        } else {
          menu.active = !menu.active;
        }
      });
    }
  }

修复逻辑说明

  • 菜单的展开状态完全由item.active属性控制,点击菜单时selectMenu会同步更新所有相关菜单的active状态
  • Angular的属性绑定会自动同步DOM的showMenu类,无需手动操作DOM元素
  • 移除了原有的嵌套点击事件,避免事件冒泡导致的逻辑冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:45:37