I have a detail page for some items in my application. This detail page contains an overview section and a few tabs under the overview section.
Users can update the overview section, after a successful update I need to reload the tabs under the overview sections.
I'm using MatBlazor to render tabs. I need to re-render the tabs after the parent component update. The typical way is to pass a callback to the child component. But here the child components (tabs to be specific) are RenderFragment which is a delegate. Here's the razor code portion of tabs in the parent component:
<div class="jds-shadow-soft-xxs jds-radius-l min-height100p pt1">
<MatTabGroup Class="jobTabs">
@foreach (var tab in tabs)
{
<MatTab>
<LabelContent>
@tab.Label
</LabelContent>
<ChildContent>
@tab.Content
</ChildContent>
</MatTab>
}
</MatTabGroup>
</div>
MatBlazor uses RenderFragment to render tab content. Here's my code in the parent component for the tabs RenderFragment
List<JobConfiguartionTabItem> tabs = new List<JobConfiguartionTabItem>();
protected override async Task OnInitializedAsync()
{
try
{
tabs.AddRange(new List<JobConfiguartionTabItem> {
new JobConfiguartionTabItem(){Label = "Scheduled Activities",Content = GetRenderFragment(typeof(JobTemplateScheduleActivityComponent))},
new JobConfiguartionTabItem(){Label = "Account Selection",Content = GetRenderFragment(typeof(AccountSelectionComponent))},
new JobConfiguartionTabItem(){Label = "Schedule",Content = GetRenderFragment(typeof(JobTemplateScheduleComponent))},
new JobConfiguartionTabItem(){Label = "Scheduled History",Content = GetRenderFragment(typeof(JobTemplateScheduledJobComponent))}
}
);
// fetching initial data for the parent component
await this.GetData();
}
catch (Exception exp)
{
Console.WriteLine("Error: " + exp);
}
}
Here's the JobConfigurationTabItem
class
public class JobConfiguartionTabItem
{
public string Label { get; set; }
public RenderFragment Content { get; set; }
}
Here's the GetRenderFragment
method in the parent component
private RenderFragment GetRenderFragment(Type component)
{
RenderFragment renderFragment = renderTreeBuilder =>
{
renderTreeBuilder.OpenComponent(0, component);
renderTreeBuilder.CloseComponent();
};
return renderFragment;
}
To simplify my requirement: I need to raise an event from the parent component, and the child component should handle the event with a handler method. In my case, child components are RenderFragment. I couldn't find a way to achieve it through RenderFragment.
Okay, I've solved the problem. My situation is Parent component needed to communicate with the child components. When the parent is updated it needs to tell the child to reload/ re-render themselves as well.
A typical way is to put a
@ref
keyword in the child markup in the parent to capture the reference. Then we can call any method of the child via the ref.In my case, I was using a
RenderFragment
which is not an instance of the child rather a delegate.I've refactored the
GetRenderFragment
method to capture the reference of the target child.I have the following method in the parent to run after the update:
RenderTreeBuilder.AddComponentReferenceCapture
is the method I was looking for to capture the reference of aRenderFragment
.