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

Blazor Server课程页面NavMenu加载章节与课时的实现方案

解决方案

1. 监听路由变化动态加载章节数据

Blazor Server的NavMenu是持久化组件,页面切换时不会自动重新初始化,核心思路是通过NavigationManager监听路由跳转事件,实时解析当前路由中的课程ID并加载对应章节数据。

实现步骤

  • 在NavMenu.razor中注入NavigationManager和课程数据服务(如ICourseService)
  • 组件初始化时订阅LocationChanged事件,同时初始化检查当前路由是否为课程页面
  • 路由变化时解析课程ID,调用API获取章节与课时数据,更新UI
  • 组件销毁时取消事件订阅,避免内存泄漏

示例代码:

@inject NavigationManager NavManager
@inject ICourseService CourseService
@implements IDisposable

<div class="top-row ps-3 navbar navbar-dark">
    <!-- 原有NavMenu固定导航内容 -->
</div>

<div class="nav-scrollable" id="main-nav">
    <nav class="flex-column">
        <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
            <span class="oi oi-home" aria-hidden="true"></span> 首页
        </NavLink>
        
        <!-- 动态渲染课程章节导航 -->
        @if (CurrentCourseChapters != null)
        {
            <CourseNavBar Chapters="CurrentCourseChapters" />
        }
    </nav>
</div>

@code {
    private List<Chapter> CurrentCourseChapters { get; set; }
    private IDisposable _locationChangedSubscription;

    protected override void OnInitialized()
    {
        _locationChangedSubscription = NavManager.LocationChanged += OnLocationChanged;
        LoadCourseChaptersFromRoute();
    }

    private async void OnLocationChanged(object sender, LocationChangedEventArgs e)
    {
        await LoadCourseChaptersFromRoute();
    }

    private async Task LoadCourseChaptersFromRoute()
    {
        // 解析路由中的课程ID,假设路由格式为 /courses/{courseId}
        var uriSegments = new Uri(NavManager.Uri).Segments;
        if (uriSegments.Length >= 2 && uriSegments[1].Equals("courses/", StringComparison.OrdinalIgnoreCase))
        {
            if (int.TryParse(uriSegments[2].TrimEnd('/'), out var courseId))
            {
                CurrentCourseChapters = await CourseService.GetChaptersWithLessonsAsync(courseId);
                StateHasChanged(); // 通知组件更新UI
            }
        }
        else
        {
            // 离开课程页面时清空章节数据
            CurrentCourseChapters = null;
            StateHasChanged();
        }
    }

    public void Dispose()
    {
        _locationChangedSubscription?.Dispose();
    }
}

2. 全局状态容器共享数据

通过全局状态容器在课程页面与NavMenu间共享章节数据,适合复杂场景下的组件状态同步。

实现步骤

  1. 创建状态容器类
public class CourseState
{
    public List<Chapter> CurrentChapters { get; private set; }
    public event Action OnStateChanged;

    public void SetChapters(List<Chapter> chapters)
    {
        CurrentChapters = chapters;
        OnStateChanged?.Invoke();
    }

    public void ClearChapters()
    {
        CurrentChapters = null;
        OnStateChanged?.Invoke();
    }
}
  1. 注册单例服务
    在Program.cs中添加:
builder.Services.AddSingleton<CourseState>();
  1. 课程页面更新状态
@inject ICourseService CourseService
@inject CourseState CourseState
@page "/courses/{CourseId:int}"

<h1>@Course.Title</h1>

@code {
    [Parameter] public int CourseId { get; set; }
    private Course Course { get; set; }

    protected override async Task OnParametersSetAsync()
    {
        Course = await CourseService.GetCourseAsync(CourseId);
        var chapters = await CourseService.GetChaptersWithLessonsAsync(CourseId);
        CourseState.SetChapters(chapters);
    }

    public void Dispose()
    {
        // 离开页面时清空章节数据
        CourseState.ClearChapters();
    }
}
  1. NavMenu监听状态变化
@inject CourseState CourseState
@implements IDisposable

<!-- 原有NavMenu内容 -->

@if (CourseState.CurrentChapters != null)
{
    <CourseNavBar Chapters="CourseState.CurrentChapters" />
}

@code {
    protected override void OnInitialized()
    {
        CourseState.OnStateChanged += StateHasChanged;
    }

    public void Dispose()
    {
        CourseState.OnStateChanged -= StateHasChanged;
    }
}

3. 关键注意事项

  • CourseNavBar组件需接收Chapters参数,使用NavLink生成规范路由(如/courses/{CourseId}/chapters/{ChapterId}/lessons/{LessonId})
  • 处理路由解析的边界情况(如无效课程ID、非课程页面路由)
  • 异步操作需正确使用async/await,避免阻塞UI
  • 调用StateHasChanged()确保数据更新后组件重新渲染

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 18:13:33