2
votes

I'm actually experimentating Blazor WebAssembly.

Everything works fine except one thing.

The idea is I want to share the same component for creation or edition of an item.

The name of the component is CreateOrEdit.razor and I have two routes :

@page "/master/maker/create"
@page "/master/maker/{id:int}"

Id is catched and stored on a property :

[Parameter]
public int Id { get; set; }

I have also a getter property to determine if we are on edit or create page.

public bool IsEditPage { get => Id > 0; }

And used into the view like this

@if (IsEditPage)
{
    <Button Clicked="OnEditButtonClicked"
            Color="@(m_EditMode ? Color.Danger : Color.Primary)" Class="mb-2">
        @(m_EditMode ? "Save" : "Edit")
    </Button>
    <Row>
        <Column ColumnSize=" ColumnSize.Is2" Class="my-auto">
            <span>ID</span>
        </Column>
        <Column ColumnSize="ColumnSize.Is8">
            <span>@Id</span>
        </Column>
        <Column ColumnSize="ColumnSize.Is2"></Column>
    </Row>
}
else
{
    <Button Clicked="OnCreateButtonClicked" Color="Color.Danger" Class="mb-2">Create</Button>
}

If we are on edition mode, we got the ID of the item and the "Edit" button displayed. Then if we click on "Edit" button the elements on the form can be edited. The "Edit" button change and become "Save". Then data is send to the API.

On creation mode, the "Save" button is displayed. Just clicking on it send data to the API. I plan to add validation but the problem is not here.

The problem below :

Assume we navigate first to the edit page "localhost/master/maker/1" and then we navigate to the creation page "localhost/master/maker/create" (problem is the same if we create an item and redirect to the edit page then); The component is not re-rendering because it shares the same one. Furthermore, the OnInitializedAsync() method is not once again called. I don't want to have 2 components separated with the same code nor force loading once again because I have some scoped services on the IoC for data caching.

Can someone help me ?

1
It seems to be an old bug, see: github.com/dotnet/aspnetcore/issues/9931 Blazor does not update the Route parameters while staying on the same page. Did you try manually setting the Id after saving the entity? You might also need to call StateHasChanged() right after that. - tocqueville
Old bug once closed and then reopen as I can see... I did as you said, manually set the Id, change the model form is binded to and others variable and then call StateHasChanged(). It first resolved the problem that occures after creation of item. The problem of navigate for example between the two routes and view not properly refresh still remains. Maybe there is another way to get same result. If not, I will separate creation and edit components until the bug got resolved. Thanks ! - Julien Guillot

1 Answers

5
votes

It's not a bug. OnInitialized/OnInitializedAsync is called once, because the component is reused, not created again. To initialize parameters you should use OnParametersSet/OnParametersSetAsync. These are called every time before rendering the component. It is described in microsoft docs [1]: https://docs.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-3.1