基于QuickGrid的Breadcrumb组件仅首次渲染正常问题排查
问题分析
首次渲染时@ChildContent会执行,触发所有BreadcrumbItem调用Context.RegisterItem(this)完成项注册,但后续渲染时,Blazor的渲染优化会跳过@ChildContent的重新执行(因引用未变化),而StartRegisteringItems又清空了列表,最终导致渲染时items为空。
解决方案
方案1:强制ChildContent每次重新渲染
通过计数器+@key指令,强制Blazor重新执行ChildContent,确保每次渲染都能完成项注册:
- 修改
Breadcrumb.razor.cs,添加触发渲染的计数器:
namespace Some.Namespace; using Microsoft.AspNetCore.Components; partial class Breadcrumb { private bool isRegisteringItems; private readonly IList<BreadcrumbItem> items; private int _renderTrigger; [Parameter] public RenderFragment? ChildContent { get; set; } public Breadcrumb() { items = new List<BreadcrumbItem>(); } private void StartRegisteringItems() { items.Clear(); isRegisteringItems = true; _renderTrigger++; } private void FinishRegisteringItems() { isRegisteringItems = false; } internal void RegisterItem(BreadcrumbItem item) { if (!isRegisteringItems) { return; } items.Add(item); } }
- 修改
Breadcrumb.razor,给ChildContent容器添加@key:
<CascadingValue TValue="Breadcrumb" Value="@(this)" IsFixed="true"> @{ StartRegisteringItems(); } <div @key="_renderTrigger"> @ChildContent </div> <Defer> @{ FinishRegisteringItems(); } <nav aria-label="breadcrumb"> <ol class="breadcrumb"> @{ var completeUrl = ""; } @foreach (var item in items) { if (!string.IsNullOrWhiteSpace(item.Url)) { completeUrl += "/" + item.Url; <li class="breadcrumb-item"><a href="@completeUrl">@item.Title</a></li> } else { <li class="breadcrumb-item active" aria-current="page">@item.Title</li> } } </ol> </nav> </Defer> </CascadingValue>
方案2:让BreadcrumbItem主动维护注册状态
修改子组件生命周期,在初始化和参数更新时主动注册,确保项信息同步:
- 修改
BreadcrumbItem.razor.cs,添加生命周期方法:
namespace Some.Namespace; using Microsoft.AspNetCore.Components; partial class BreadcrumbItem { [CascadingParameter] public Breadcrumb Context { get; set; } = default!; [Parameter] public string? Url { get; set; } [Parameter] [EditorRequired] public string Title { get; set; } = default!; protected override void OnInitialized() { base.OnInitialized(); Context.RegisterItem(this); } protected override void OnParametersSet() { base.OnParametersSet(); Context.RegisterItem(this); } }
- 修改
Breadcrumb的RegisterItem方法,避免重复添加:
internal void RegisterItem(BreadcrumbItem item) { if (!isRegisteringItems) { return; } if (!items.Contains(item)) { items.Add(item); } }
内容的提问来源于stack exchange,提问作者Streamline
相关产品推荐
相关产品推荐

