'How can I save a Blazor Component instance in a variable and render it in my .cshtml
Considering I have a class called Tab.
public class Tab
{
public Guid Id { get; }
public bool IsVisible { get; set; }
protected Tab()
{
Id = Guid.NewGuid();
}
}
I want to strictly couple these tabs to a Blazor Component instance and render those instances by iterating over the tabs. I want to have control over when a Component is created and when it is destroyed again.
I want to do this because that way I can persist the state for each component.
Here is the problem with the easy approach. Considering something like this:
@code {
public void CreateNewTabAndRemoveOldTab()
{
Tabs.RemoveAt(0);
Tabs.Add(new Tab());
}
}
foreach (var tab in Tabs)
{
<MyTabComponent/>
}
The newly created tab will simply take over the state of the removed tab. OnInitialized will not be called.
I have looked into RenderFragment, but it does not look like its working property. The problem is that the Blazor Framework will still decide when a new component is created (thus calling OnInitialized) or when existing instance are used.
Solution 1:[1]
If I read this correctly, Tab is a class, not a component. You need to decouple your list of Tabs from the component that renders them. Your list of tabs lives in a service, the scope depends on what you're doing with them. Your Tab Component displays the currently selected Tab in the list. If you show a little more of your logic I can probably show you a relevant working example.
Solution 2:[2]
Check this
@ref it's reference to your component it's added to list of components.
@implements IDisposable
@foreach (var tab in tabs)
{
<MyTabComponent @ref=@TabRef Tab=@tab />
}
@code {
List<Tab> tabs = new List<Tab>();
List<MyTabComponent> tabsComp = new List<MyTabComponent>();
MyTabComponent TabRef {
set { tabsComp.Add(value); }
}
public void CreateNewTabAndRemoveOldTab()
{
tabs.RemoveAt(0);
tabs.Add(new Tab());
}
public void Dispose()
{
}
}
Solution 3:[3]
MyTabs.razor
<CascadingValue Value="@this" IsFixed="true">
foreach (var tab in Tabs)
{
<MyTabComponent/>
}
</CascadingValue>
@code{
private List<MyTabComponent> Tabs;
public void Register(MyTabComponent tab)
{
this.Tabs.Add(tab);
}
public void UnRegister(MyTabComponent tab)
{
this.Tabs.Remove(tab);
}
}
MyTabComponent.razor
@implements IDisposable
<div></div>
@code{
[CascadingParameter]
protected MyTabs Context { get; set; }
protected override void OnInitialized()
{
Context?.Register(this);
// implement your logic here
}
public void Dispose()
{
Context?.UnRegister(this);
// implement your logic here
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | MrC aka Shaun Curtis |
| Solution 2 | user3529134 |
| Solution 3 | Dharman |
