Search code examples
.netblazortelerikblazor-webassembly

Blazor Wasm - CascadingValue update from descending component


I want a global loading indicator on my application. I have already a component for that, LoadingIndicator.razor:

<CascadingValue Value="this">
    <TelerikLoaderContainer Visible="@( IsVisible )" Text="@Text" />
    @ChildContent
</CascadingValue>

@code {

    [Parameter]

    public RenderFragment? ChildContent { get; set; }


    [Parameter]
    public bool IsVisible { get; set; }

    [Parameter]
    public string Text { get; set; } }

and somewhere in my component tree I try the following, childComponent.razor

[CascadingParameter]
protected LoadingContainer LoadingContainer { get; set; }

protected override async Task OnInitializedAsync()
{
    LoadingContainer.Text = "test";
    LoadingContainer.IsVisible = true;
}

according to the warning BL0005 thats not allowed due to inconsistent Ui (possibly). But how could I show the loading indicator on my child components? I would not like to use inheritance because I want to be flexible whether and where I want to use it. The CascadingValue is applied at the MainLayout level so all components have it available.


Solution

  • You want to trigger an update in the parent.

    <CascadingValue Value="this">
        <TelerikLoaderContainer Visible="@( IsVisible )" Text="@Text" />
        @ChildContent
    </CascadingValue>
    
    @code {
    
        [Parameter]
        public RenderFragment? ChildContent { get; set; }
    
        //[Parameter] -- you can make these private fields now
        public bool IsVisible { get; set; }
    
        //[Parameter] -- same
        public string Text { get; set; } 
    
        public void ShowLoader(string text)
        {
            Text = text;
            IsVisible = true;
            StateHasChanged();
        }
    }
    

    and use it like this

    protected override async Task OnInitializedAsync()
    {
        //LoadingContainer.Text = "test";
        //LoadingContainer.IsVisible = true;
        LoadingContainer.ShowLoader("test");
    }