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

Ionic菜单选中一项后所有项均激活问题求助

动态菜单导航项全部激活且链接异常问题

我开发了一个基于用户权限的应用,会根据用户所处环境及对应可访问功能生成导航菜单。菜单默认包含Home导航链接和退出按钮,其余导航项为动态加载,分为**基础项(basic)和可折叠项(collapsable)**两种类型。

应用启动时用户会跳转至Home页面并加载权限列表,但现在出现异常:选中任意菜单项导航时,所有菜单导航项都会被标记为激活状态(统一添加menu-item-active类),并且所有项的href值都会被修改为最后选中项的链接。

编辑1:选中菜单项时会调用closeMenu()方法,我在该方法中加入了fillNavigationItems()并打印navigationItems,确认数据本身是正确的,各项链接无误,但浏览器开发者工具显示所有项都带有menu-item-active类,href值为最后选中项的链接。


相关代码

<ion-menu type="overlay" [contentId]="contentId">
  <ion-header>
    <ion-toolbar>
      <ion-menu-button slot="start">
        <ion-icon name="close-outline"></ion-icon>
      </ion-menu-button>
      <ion-title>MENU</ion-title>
    </ion-toolbar>
  </ion-header>

  <ion-content>
    <ion-list class="ion-padding">
      <a routerLink="home"
         [routerLinkActive]="'menu-item-active'"
         [routerLinkActiveOptions]="{ exact: true }"
         class="menu-item"
         (click)="closeMenu()">
          <mat-icon>home</mat-icon>
          <ion-label>Home</ion-label>
      </a>

      <ng-container *ngFor="let item of navigationItems">
        <ng-container *ngIf="item.type === 'basic'">
          <a [routerLink]="item.link"
             [routerLinkActive]="'menu-item-active'"
             [routerLinkActiveOptions]="{ exact: true }"
             class="menu-item"
             (click)="closeMenu()">
              <mat-icon>{{ item.icon }}</mat-icon>
              <ion-label>{{ item.title }}</ion-label>
          </a>
        </ng-container>

        <ng-container *ngIf="item.type === 'collapsable'">
          <ion-accordion-group>
            <ion-accordion>
              <ion-item slot="header" class="menu-item-header">
                <mat-icon class="menu-item-header-icon">{{ item.icon }}</mat-icon>
                <ion-label>{{ item.title }}</ion-label>
              </ion-item>

              <div slot="content">
                <ion-list *ngIf="item.children && item.children.length > 0">
                  <a *ngFor="let child of item.children"
                     [routerLink]="child.link"
                     [routerLinkActive]="'menu-item-active'"
                     [routerLinkActiveOptions]="{ exact: true }"
                     class="menu-item"
                     (click)="closeMenu()">
                      <mat-icon>{{ child.icon }}</mat-icon>
                      <ion-label>{{ child.title }}</ion-label>
                  </a>
                </ion-list>
              </div>
            </ion-accordion>
          </ion-accordion-group>
        </ng-container>
      </ng-container>

      <ion-button class="logout-button" fill="clear" (click)="onLogout()">
        <span class="logout-button-content">
          <ion-icon name="log-out-outline"></ion-icon>
          <ion-label>Sair</ion-label>
        </span>
      </ion-button>
    </ion-list>
  </ion-content>

  <ion-footer>
    <ion-item>footer</ion-item>
  </ion-footer>
</ion-menu>
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import { AuthService } from 'src/app/core/auth/auth.service';
import { MenuNavigationItem } from './menu.model';
import { UserAccessService } from 'src/app/core/user-access/user-access.service';
import { Functionality } from 'src/app/core/auth/auth.model';
import { MenuController } from '@ionic/angular';

@Component({
  selector: 'app-menu',
  templateUrl: './menu.component.html',
  styleUrls: ['./menu.component.scss'],
})
export class MenuComponent implements OnInit, OnDestroy {
  private _unsubscribeAll: Subject<any> = new Subject<any>();

  @Input() contentId: string;

  public navigationItems: MenuNavigationItem[] = [];

  constructor(
    private _authService: AuthService,
    private _userAccessService: UserAccessService,
    private _menuController: MenuController
  ) { }

  private verifyUserAccessInEnvironment(funccionalities: Functionality[]): boolean {
    return funccionalities.length === 0 ? false : true;
  }

  private fillNavigationItems(): void {
    let filteredFuncionalities: Functionality[] = [];

    this._userAccessService.getFilteredFuncionalitiesIds()
      .then((functionalities: Functionality[]) => {

        filteredFuncionalities = functionalities;
        this.navigationItems = this._userAccessService.getPowerBiFunctionalitiesNavigation(filteredFuncionalities);
        this._userAccessService.hasPowerBiAccessInCurrentEnvironment
          .next(this.verifyUserAccessInEnvironment(functionalities));
      });
  }

  ngOnInit(): void {
    this._userAccessService.currentEnvironmentId
      .pipe(takeUntil(this._unsubscribeAll))
      .subscribe(() => {
        this.fillNavigationItems();
      });
  }

  closeMenu(): void {
    this._menuController.close();
  }

  onLogout(): void {
    this._authService.logout();
  }

  ngOnDestroy(): void {
    this._unsubscribeAll.next(null);
    this._unsubscribeAll.complete();
  }

}

导航项示例

[
    {
        "id": "703",
        "title": "ITEM 1",
        "type": "collapsable",
        "icon": "business",
        "children": [
            {
                "id": "778",
                "title": "ITEM 1.1",
                "type": "basic",
                "icon": "",
                "link": "item/778",
                "children": []
            },
            {
                "id": "838",
                "title": "ITEM 1.2",
                "type": "basic",
                "icon": "",
                "link": "item/838",
                "children": []
            },
            {
                "id": "751",
                "title": "ITEM 1.3",
                "type": "basic",
                "icon": "",
                "link": "item/751",
                "children": []
            }
        ]
    },
    {
        "id": "701",
        "title": "ITEM 2",
        "type": "collapsable",
        "icon": "pets",
        "children": [
            {
                "id": "813",
                "title": "ITEM 2.1",
                "type": "basic",
                "icon": "",
                "link": "item/813",
                "children": []
            },
            {
                "id": "810",
                "title": "ITEM 2.2",
                "type": "basic",
                "icon": "",
                "link": "item/810",
                "children": []
            }
        ]
    }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 12:07:06