Angular 2中如何对非管理员用户隐藏Maintenance菜单项?
如何根据用户权限隐藏Angular中的Maintenance菜单项
我需要对非管理员用户隐藏Maintenance菜单项。目前已通过IsAdminGuard路由守卫限制了该菜单对应链接的访问权限,但更希望直接隐藏整个菜单。我的
app.menu.ts中定义了如下初始菜单项:import { MenuItem } from '../fw/services/menu.service'; export let initialMenuItems: Array<MenuItem> = [ { text: 'Dashboard', icon: 'glyphicon-dashboard', route: '/authenticated/dashboard', submenu: null }, { text: 'Books', icon: 'glyphicon-book', route: null, submenu: [{...}] }, { text: 'Authors', icon: 'glyphicon-user', route: null, submenu: [{...}], }, { text: 'Maintenance', icon: 'glyphicon-wrench', route: null, submenu: [{...}] } ]
menu.service.ts代码如下:import { Injectable } from '@angular/core'; export interface MenuItem { text: string, icon: string, route: string, submenu: Array<MenuItem> } @Injectable() export class MenuService { items: Array<MenuItem>; isVertical = false; showingLeftSideMenu = false; displayMaintainance = false; showMaintenance() { var currentUser = JSON.parse(localStorage.getItem('currentUser')); if (currentUser.isAdmin === true) { return true; } else { return false; } }; }我已实现的路由守卫代码:
{ path: 'book-detail/:id/:operation', component: BookDetailComponent, canActivate: [IsAdminGuard] }但不知如何在
app.menu.ts中使用menu.service.ts里的showMaintenance()方法,请问实现隐藏菜单的最佳方式是什么?
嘿,其实不用在app.menu.ts里硬套服务方法,Angular里有更优雅的动态菜单处理方式,给你两种实用的实现方案:
方案一:在MenuService中动态构建权限菜单
这种方式把菜单的权限过滤逻辑封装在服务里,组件直接用处理后的菜单数据就行,代码更干净:
- 先改造你的
MenuService,把初始菜单项移到服务内部,然后添加初始化方法过滤权限:
import { Injectable } from '@angular/core'; export interface MenuItem { text: string, icon: string, route: string, submenu: Array<MenuItem> } @Injectable() export class MenuService { items: Array<MenuItem>; isVertical = false; showingLeftSideMenu = false; displayMaintainance = false; // 将初始菜单定义移到服务内部 private initialMenuItems: Array<MenuItem> = [ { text: 'Dashboard', icon: 'glyphicon-dashboard', route: '/authenticated/dashboard', submenu: null }, { text: 'Books', icon: 'glyphicon-book', route: null, submenu: [{...}] }, { text: 'Authors', icon: 'glyphicon-user', route: null, submenu: [{...}], }, { text: 'Maintenance', icon: 'glyphicon-wrench', route: null, submenu: [{...}] } ]; constructor() { // 初始化时就过滤菜单 this.initMenuWithPermissions(); } private initMenuWithPermissions() { const currentUser = JSON.parse(localStorage.getItem('currentUser')); // 过滤掉非管理员用户的Maintenance项 this.items = this.initialMenuItems.filter(item => { if (item.text === 'Maintenance') { // 注意加可选链,避免currentUser为null时报错 return currentUser?.isAdmin === true; } return true; }); } // 如果用户登录状态变化(比如切换账号),调用这个方法更新菜单 refreshMenu() { this.initMenuWithPermissions(); } showMaintenance() { const currentUser = JSON.parse(localStorage.getItem('currentUser')); return currentUser?.isAdmin === true; }; }
- 之后在你的菜单组件里,直接注入
MenuService,用menuService.items来渲染菜单就好——非管理员用户的菜单里自动就没有Maintenance项了。
方案二:在菜单模板中直接做权限判断
如果不想改动服务结构,也可以在渲染菜单的模板里直接加条件判断,快速实现隐藏:
- 先在菜单组件中注入
MenuService(要声明为public,这样模板能访问):
import { Component } from '@angular/core'; import { MenuService } from './menu.service'; @Component({ selector: 'app-menu', templateUrl: './menu.component.html' }) export class MenuComponent { constructor(public menuService: MenuService) {} }
- 然后在菜单模板里给Maintenance项加
*ngIf判断:
<ul class="menu"> <li *ngFor="let item of menuService.items"> <!-- 普通菜单项正常渲染 --> <div *ngIf="item.text !== 'Maintenance'"> <a [routerLink]="item.route"> <span class="glyphicon {{item.icon}}"></span> {{item.text}} </a> <!-- 子菜单渲染逻辑这里省略 --> </div> <!-- 只有管理员能看到Maintenance --> <div *ngIf="item.text === 'Maintenance' && menuService.showMaintenance()"> <a [routerLink]="item.route"> <span class="glyphicon {{item.icon}}"></span> {{item.text}} </a> <!-- 子菜单渲染逻辑这里省略 --> </div> </li> </ul>
额外小建议
- 建议把权限判断逻辑抽离到单独的
AuthService里,比如写一个isAdmin()方法,这样路由守卫、菜单服务都能复用,避免重复代码。 - 如果用户有登录/注销、切换账号的场景,记得在状态变化时调用菜单的刷新方法(比如方案一里的
refreshMenu()),保证菜单能动态更新。
内容的提问来源于stack exchange,提问作者Frey_ja
相关产品推荐
相关产品推荐

