Streamline
Streamline

Reputation: 982

Component renders only first time correctly

I've built a simplified Breadcrumb component based on the QuickGrid component and i don't understand why the content is not rendered correctly:

Breadcrumb.razor.cs

namespace Some.Namespace;

using Microsoft.AspNetCore.Components;

partial class Breadcrumb
{
    private bool isRegisteringItems;
    private readonly IList<BreadcrumbItem> items;

    [Parameter]
    public RenderFragment? ChildContent { get; set; }

    public Breadcrumb()
    {
        items = new List<BreadcrumbItem>();
    }

    private void StartRegisteringItems()
    {
        items.Clear();
        isRegisteringItems = true;
    }

    private void FinishRegisteringItems()
    {
        isRegisteringItems = false;
    }

    internal void RegisterItem(BreadcrumbItem item)
    {
        if (!isRegisteringItems)
        {
            return;
        }

        items.Add(item);
    }
}

Breadcrumb.razor

<CascadingValue TValue="Breadcrumb" Value="@(this)" IsFixed="true">
    @{
        StartRegisteringItems(); 
    }
    @ChildContent
    @* Defer is a copy from the QuickGrid repo. *@
    <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>

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!;
}

Breadcrumb.razor

@{
    Context.RegisterItem(this);
}

The first time it renders it contains all desired items, but all following renders do not have any items anymore. The Start/Finish methods are called as expected, but the items are not registered upon rendering. A customized grid based on this setup however renders correctly.

Upvotes: 0

Views: 54

Answers (1)

DanielD
DanielD

Reputation: 396

Suggestion:

I guess you're missing a StateHasChanged() after you've added your breadcrumbItem inside your register method. Take a look here, that's a similiar approach than what you are trying to do: blazor-university Tab Control

Solution (as mentioned by you):

Seems like the component wasn't fully loaded when you triggered your RegisterItem method and therefore moving it inside the OnInitialized method solved your issue.

Upvotes: 1

Related Questions