Blazor and communication between pages, layouts and components

61 Views Asked by At

I am trying to figure out the cleanest way to communicate between components, layouts and pages in Blazor.

I have a Header component that makes a data call to retrieve data based on an id. This Header component is in the Main Layout of my app. The id that the Header component needs gets set on each page /mypage/{id} Currently I have an AppState service that is storing the id which the Header component uses to get its data. Each page sets/updates the id. Each page also is displaying that header component due to the Layout it is using.

What im trying to get my head wrapped around is I need to overwrite or display different content based on the data in the header. For example if the user doesnt have access to that id record, it would display a message or error. I wanted to make it where I dont have to add the same logic on each page and Id have it in one place.

I havent updated to .net 8 yet, but I was looking to see if I coudld do it with sections in .net 8.

Here is a watered down version. I wrote this just to get the idea across, not sure if this would even compile. I need to determine how to show different content besides the @body content. I feel like it is hard to explain. Could I use nested layouts? That seems kind of messy.

I can try and clarify things if need be, but Im at a loss.

Any suggestions is helpful. Thanks.

MyHeader.razor

@inject IAppState AppState;

<h3>My Header</h3>

@if(AppState?.RecordId != null)
{
    @AppState.RecordId
}

@code {

    [Parameter]
    public Action<MyViewModel?>? OnHeaderLoaded { get; set; }

    protected override async Task OnParametersSetAsync()
    {
        //Dummy up return data.  This actually gets returned in http call.
        MyViewModel response = new MyViewModel() { RecordId = AppState.RecordId, SomeCondition = true };

        //fire action  (could be an Event Callback too.)
        OnHeaderLoaded?.Invoke(response);

    }
}

MainLayout

<MyHeader OnHeaderLoaded = "OnHeaderLoaded"/>
// Need to determine what to show here based on SomeCondition from ViewModel and id from MyHeaderComponent.. but id comes from pages.
@Body 

@code {
    public void OnHeaderLoaded() {
    ...
    }
}

Index.razor

@inject IAppState AppState
@page "/{id:int}"


<h1>Index Page @id</h1>

@code {
    [Parameter]
    public int id { get; set; }

    protected override async Task OnParametersSetAsync()
    {
        AppState.RecordId = id;

        await base.OnParametersSetAsync();
    }
}
0

There are 0 best solutions below