Angular:如何通过ASP.NET Core Web API数据库数据实现动态菜单
实现ASP.NET Core + Angular 11 动态菜单完整步骤
一、ASP.NET Core Web API 后端实现
- 第一步创建数据表对应实体类
按照你设计的MainMenu、subMenu表字段,在后端项目中创建对应实体,示例结构如下:public class MainMenu { public int Id { get; set; } public string MenuName { get; set; } public string RoutePath { get; set; } public string Icon { get; set; } public int SortOrder { get; set; } public bool IsActive { get; set; } // 关联子菜单 public List<SubMenu> SubMenus { get; set; } } public class SubMenu { public int Id { get; set; } public int MainMenuId { get; set; } public string SubMenuName { get; set; } public string RoutePath { get; set; } public string Icon { get; set; } public int SortOrder { get; set; } public bool IsActive { get; set; } } - 配置数据库上下文与查询逻辑
在你的DbContext中添加对应DbSet,配置主菜单和子菜单的一对多关联关系,确保查询主菜单时可以关联带出对应激活状态的子菜单。 - 开发菜单查询接口
新增MenuController,编写GET接口查询所有激活状态的菜单,按SortOrder排序后返回,示例代码:[ApiController] [Route("api/[controller]")] public class MenuController : ControllerBase { private readonly YourDbContext _dbContext; public MenuController(YourDbContext dbContext) { _dbContext = dbContext; } [HttpGet] public async Task<IActionResult> GetAllMenus() { var menus = await _dbContext.MainMenus .Include(m => m.SubMenus.Where(s => s.IsActive)) .Where(m => m.IsActive) .OrderBy(m => m.SortOrder) .ToListAsync(); return Ok(menus); } } - 配置跨域策略
在后端启动配置中添加CORS规则,允许Angular运行地址(默认是http://localhost:4200)访问接口,避免跨域报错。 - 接口测试
运行后端项目后访问GET http://你的后端地址/api/menu,确认返回的JSON结构为嵌套的主/子菜单格式即可。
二、Angular 11 前端实现
- 第一步创建菜单类型定义
在src/app下新建models/menu.ts文件,定义和后端返回结构匹配的接口:export interface SubMenu { id: number; mainMenuId: number; subMenuName: string; routePath: string; icon: string; sortOrder: number; isActive: boolean; } export interface MainMenu { id: number; menuName: string; routePath: string; icon: string; sortOrder: number; isActive: boolean; subMenus: SubMenu[]; } - 创建菜单请求服务
执行命令ng generate service services/menu创建菜单服务,在服务中注入HttpClient,编写获取菜单的方法:import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { MainMenu } from '../models/menu'; @Injectable({ providedIn: 'root' }) export class MenuService { private apiUrl = 'http://你的后端地址/api/menu'; constructor(private http: HttpClient) {} getMenus(): Observable<MainMenu[]> { return this.http.get<MainMenu[]>(this.apiUrl); } } - 创建菜单组件
执行命令ng generate component components/side-menu创建菜单组件,在组件ts文件中注入菜单服务,初始化时拉取菜单数据:import { Component, OnInit } from '@angular/core'; import { MenuService } from '../../services/menu.service'; import { MainMenu } from '../../models/menu'; @Component({ selector: 'app-side-menu', templateUrl: './side-menu.component.html', styleUrls: ['./side-menu.component.css'] }) export class SideMenuComponent implements OnInit { menuList: MainMenu[] = []; constructor(private menuService: MenuService) {} ngOnInit(): void { this.menuService.getMenus().subscribe(res => { this.menuList = res; }); } } - 编写菜单组件模板
在side-menu.component.html中通过*ngFor循环渲染动态菜单,示例代码:<ul class="main-menu"> <li *ngFor="let mainMenu of menuList"> <a [routerLink]="mainMenu.routePath"> <i class="{{mainMenu.icon}}"></i> <span>{{mainMenu.menuName}}</span> </a> <ul class="sub-menu" *ngIf="mainMenu.subMenus?.length"> <li *ngFor="let subMenu of mainMenu.subMenus"> <a [routerLink]="subMenu.routePath"> <i class="{{subMenu.icon}}"></i> <span>{{subMenu.subMenuName}}</span> </a> </li> </ul> </li> </ul> - 路由配置与菜单挂载
在app-routing.module.ts中注册所有菜单对应的路由规则,确保菜单的routePath和路由配置的path完全匹配,最后把<app-side-menu></app-side-menu>标签放到app.component.html需要显示菜单的位置即可。
三、常见问题排查
- 菜单不显示时先打开浏览器控制台的网络面板,确认后端接口请求成功,返回数据结构和类型定义匹配
- 路由跳转失败时检查路由配置的path和菜单返回的
routePath是否存在大小写、斜杠等字符差异 - 跨域报错时确认后端CORS配置的允许源包含当前Angular的运行地址
内容的提问来源于stack exchange,提问作者Sikha Rani Mohapatra
相关产品推荐
相关产品推荐

