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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 02:39:02