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

Angular下拉菜单异常:点击Admin才展开却始终处于展开状态

解决Angular菜单始终展开的问题

当前问题的核心是没有通过状态变量控制子菜单的显示/隐藏,仅通过menuItem.children != null判断会导致所有带子项的菜单一直展开。以下是具体修复方案:

步骤1:添加菜单展开状态管理

修改sidebar.component.ts,新增状态变量跟踪每个菜单的展开状态,同时添加切换方法:

import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';

declare interface RouteInfo {
  path: string;
  title: string;
  icon: string;
  class: string;
  children: any[];
}

export const ROUTES: RouteInfo[] = [
  { path: '/home', title: 'Home', icon: 'dashboard', class: '', children: [] },
  { path: '/photo', title: 'Photo', icon: 'person', class: '', children: [] },
  {
    path: '/admin', title: 'Admin', icon: 'library_books', class: '', children: [
      { path: '/person', title: 'Person List', icon: 'bubble_chart', class: '' },
      { path: '/setting', title: 'Setting', icon: 'bubble_chart', class: '' },
    ]
  }
];

@Component({
  selector: 'app-sidebar',
  templateUrl: './sidebar.component.html',
  styleUrls: ['./sidebar.component.css']
})
export class SidebarComponent implements OnInit {
  menuItems: RouteInfo[];
  // 用菜单标题作为键,记录展开状态
  expandedMenus: { [key: string]: boolean } = {};

  constructor(private router: Router) { }

  ngOnInit() {
    this.menuItems = ROUTES.filter(menuItem => menuItem);
    // 初始化所有菜单为折叠状态
    this.menuItems.forEach(item => {
      this.expandedMenus[item.title] = false;
    });

    // 可选:路由切换时自动展开对应父菜单
    this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        this.menuItems.forEach(item => {
          if (item.children.length > 0) {
            const hasActiveChild = item.children.some(child => 
              this.router.isActive(item.path + child.path, false)
            );
            this.expandedMenus[item.title] = hasActiveChild;
          }
        });
      }
    });
  }

  // 切换菜单展开/折叠状态
  toggleMenu(menuTitle: string) {
    this.expandedMenus[menuTitle] = !this.expandedMenus[menuTitle];
  }
}

步骤2:修改模板,绑定状态控制子菜单显示

修改sidebar.component.html,用状态变量替代原有的*ngIf条件,同时给主菜单添加点击切换事件:

<div class="sidebar-wrapper">
  <ul class="nav">
    <li routerLinkActive="active" *ngFor="let menuItem of menuItems" class="{{menuItem.class}} nav-item">
      <!-- 点击主菜单时切换展开状态 -->
      <a class="nav-link" [routerLink]="[menuItem.path]" (click)="toggleMenu(menuItem.title)">
        <i class="material-icons">{{menuItem.icon}}</i>
        <p>
          {{menuItem.title}}
          <!-- 可选:添加展开/折叠图标提示 -->
          <i class="material-icons" style="font-size:16px;">
            {{expandedMenus[menuItem.title] ? 'expand_less' : 'expand_more'}}
          </i>
        </p>
      </a>
      
      <!-- 仅当菜单有子项且处于展开状态时显示子菜单 -->
      <div *ngIf="menuItem.children.length > 0 && expandedMenus[menuItem.title]">
        <ul>
          <li routerLinkActive="active" class="{{menuItem.class}} nav-item" *ngFor="let child of menuItem.children">
            <a [routerLink]="[menuItem.path + child.path]">{{child.title}}</a>
            <hr>
          </li>
        </ul>
      </div>
    </li>
  </ul>
</div>

可选优化

  • 如果希望点击主菜单仅展开子菜单不导航,可以修改点击事件为:(click)="toggleMenu(menuItem.title); $event.preventDefault()"
  • 可以给展开的菜单添加自定义CSS样式,比如改变背景色或边框,提升视觉区分度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 10:33:29