Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blazor (Razor Components) Refresh Child Component from Parent Component

I have a simple child Blazor component (MyModal) like so:

<div class="modal">
    <h3>@Title</h3>
    @BodyTemplate
</div>

@code
{
    [Parameter] string Title { get; set; }
    [Parameter] RenderFragment BodyTemplate { get; set; }
}

In my Parent component I'm calling it like so:

<MyModal Title="Super Cool Modal">
        <BodyTemplate>
            @MyObject.Name
        </BodyTemplate>
</MyModal>

public MyObject MyObject { get; set; } = new MyObject();

Later on after the page has initially rendered I update MyObject but the Child component itself referencing @MyObject.Name never updates.

Seems I have to force refresh on the child object after I've updated the Object (StateHasChanged) but not sure how to do this with this example.

like image 337
aherrick Avatar asked Jul 04 '19 19:07

aherrick


People also ask

Can Blazor components be nested?

In the Blazor application, a component can also be nested inside another component using the HTML syntax. For example, if you want to nest counter component inside the index component then you need to use <Counter /> within the Index component.

What is RenderFragment in Blazor?

RenderFragment is used to render components or content at run time in Blazor. The RenderFragment class allows you to create the required content or component in a dynamic manner at runtime.


4 Answers

You can try this

Child

Create a public refresh method that you can call from parent

<div class="modal">
    <h3>@Title</h3>
    @BodyTemplate
</div>

@code
{
    [Parameter] string Title { get; set; }
    [Parameter] RenderFragment BodyTemplate { get; set; }

    public void RefreshMe()
    {
        StateHasChanged();
    }
}

Parent

Call child refresh method

<MyModal Title="Super Cool Modal"
         @ref="ChildComponent">
        <BodyTemplate>
            @MyObject.Name
        </BodyTemplate>
</MyModal>
@code
{
   public MyObject MyObject { get; set; } = new MyObject();
   protected UploadDownloadComponent ChildComponent;

   //Call this method to update the child
   private void Change(TreeEventArgs args)
   {
       ChildComponent.RefreshMe();
   }
}
like image 63
Amine Avatar answered Oct 24 '22 07:10

Amine


You can do "OnParametersSetAsync()" on child component:

Parent component:

<childCompoment param="@paramParent" />

Child component:

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

protected override async Task OnInitializedAsync(){await Refresh();}

async Task Refresh(){}
like image 29
Martin VU Avatar answered Oct 24 '22 06:10

Martin VU


Since <MyModal> has a RenderFragment parameter it's enough to call StateHasChanged() on the parent component, it will recalculate and render all child components with parameters from the parent.

like image 26
hultqvist Avatar answered Oct 24 '22 06:10

hultqvist


You can just use CascadingParameter.

In your parent component, just call child component like this:

<CascadingValue Value="selectedChats[0].Id" Name="chatID">
     <AdminChatComponent> </AdminChatComponent>
</CascadingValue>

Child Component:

[CascadingParameter(Name ="chatID")]
public string chatID { get; set; }

After that, all you need to do is just make a OnParametersSetAsync method in child component andjust bind your value in parent component. In my case I binded my value to datagrid row select.

After that whenever binded value changes on parent component, also your child component will trigger OnParametersSetAsync method.

like image 2
SBU Avatar answered Oct 24 '22 05:10

SBU