Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blazor component : refresh parent when model is updated from child component

I'm using Server-side Blazor components in ASP.NET Core 3 preview 4.

I have a parent component, and child components, using the same shared model, like this :

Model :

public class CountModel
{
    public int Count { get; set; }

    public void Increment()
    {
        Count++;
    }
}

Parent component :

@page "/count"

<CascadingValue Value="currentCount">
    <h1>Count parent</h1>

    <p>Current count is : @currentCount.Count</p>

    <button class="btn btn-primary" onclick="@currentCount.Increment">+1 from parent</button>

    <CountChild></CountChild>
</CascadingValue>

@functions {
    private CountModel currentCount = new CountModel();
}

Child component :

<h1>Count child</h1>

<p>Current count is : @currentCount.Count</p>

<button class="btn btn-primary" onclick="@currentCount.Increment">+1 from child</button>


@functions {
    [CascadingParameter]
    private CountModel currentCount { get; set; }
}

It's the same instance of the model used for the parent and the child. When the model is updated from the parent, both display the correct incremented value. When it's updated from the child, only the child display the correct value.

How can I force the parent component to be refreshed when it is updated from the child ?

Note, here I have a function to update the model, but I would like the solution to work when data is bound to an input.

like image 919
glacasa Avatar asked Apr 20 '19 15:04

glacasa


People also ask

How do I automatically refresh a component in Blazor?

Blazor detects the UI changes in common scenarios like EventCallback (button click, dropdown select, etc.), and refreshes the component.

How pass data from child component to parent component in Blazor?

Child component to parent component communication For this the child component exposes an event. The parent component assigns a callback method to the child component's event. In Blazor, to expose an event we use EventCallback .

How do you Rerender a Blazor component?

To force a component to rerender, use the “StateHasChanged” method in Blazor, to notify that the state has been changed and requires re-rendering.


3 Answers

Create a shared service. Subscribe to the service's RefreshRequested event in the parent and Invoke() from the child. In the parent method call StateHasChanged();

public interface IMyService
{
    event Action RefreshRequested;
    void CallRequestRefresh();
 }

public class MyService: IMyService
{
    public event Action RefreshRequested;
    public void CallRequestRefresh()
    {
         RefreshRequested?.Invoke();
    }
}


//child component
MyService.CallRequestRefresh();


//parent component
MyService.RefreshRequested += RefreshMe;

private void RefreshMe()
{
    StateHasChanged();
}
like image 65
Laurence73 Avatar answered Oct 21 '22 00:10

Laurence73


Update Parent State by calling it's StateHasChanged method

Create a Method to Update the State on Parent:

public void RefreshState(){
     this.StateHasChanged();
}

Pass the Parent to the Child's by cascading Value or Parameter Example:

<CascadingValue Value="this">
  <ChildComponent /> 
</CascadingValue>

Now on the Child's component declare the Cascading Parameter:

[CascadingParameter]
public ParentPageType _Parent { get; set; }

And Now When you want to refresh the parent just call:

_Parent.RefreshState();
like image 40
Daniel Avatar answered Oct 21 '22 00:10

Daniel


The flow of Cascading parameters is downwards. For your parent to be refreshed, you want to provide a callback that the child component can call, passing it some value. I've already shown in the Blazor section here how to create a callback on the parent component, and how to trigger the callback, passing it a value.

like image 8
enet Avatar answered Oct 20 '22 23:10

enet