Reputation: 359
Consider the following Blazor ParentComponent
that renders a list of ChildComponent
s:
<input type="date" @bind-Value="date" />
<button type="button" @onclick="ChangeDate"> Filter </button>
foreach(var i in list)
{
<ChildComponent Id="i.Id" Date="date" />
}
@code{
List<int> list; //a list of ids for this example
DateTime date = DateTime.Today; //date ChildComponent should be filtered by
async Task ChangeDate()
{
//What do I write here to call StateHasChanged() on ChildComponents?
}
}
How would I call StateHasChanged()
on all ChildComponent
's from ParentComponent
?
Upvotes: 1
Views: 895
Reputation: 30046
In general this is the job of a Service. Your data lives in (lets call it) DateService. DateService contains a list of items with IDs and Dates. When you change the date (in any or all the list items) as you do here in the "Page" component, you trigger a ListHasChanged event/delegate that you have set up in the service. Each ChildComponent
uses Dependency Injection to get the service and registers an internal event handler to the event in OnInitializedAsync
. The event handler re-renders if necessary. Note: Always call StateHasChanged
with Invoke - you can never guarantee which thread is calling it with event handlers. I've shown a generic event handler which re-renders a component.
protected async void RenderAsync(object sender, EventArgs e) => await this.InvokeAsync(StateHasChanged);
I'll post some more detailed code if requested.
MS detail on Services and DI here
Upvotes: 1