C# 如何在Blazor中保留组件实例
我有一个类似的组件,我会在第一次渲染时保存C# 如何在Blazor中保留组件实例,c#,asp.net-core,blazor,C#,Asp.net Core,Blazor,我有一个类似的组件,我会在第一次渲染时保存InnerComponent的实例,每次都渲染相同的实例,而不重新插入它 @if(isVisible) { <InnerComponent @ref="@_InnerComponent" @key="@("InnerComponentKey")"> @ChildContent </InnerComponent> } @code{
InnerComponent
的实例,每次都渲染相同的实例,而不重新插入它
@if(isVisible)
{
<InnerComponent @ref="@_InnerComponent" @key="@("InnerComponentKey")">
@ChildContent
</InnerComponent>
}
@code{
[Parameter] public InnerComponent _InnerComponent { get; set; }
private bool IsVisible { get; set; }
}
因为我问的问题不多,所以我接受了批评:)
提前谢谢
简化示例:
假设我们有以下组件,我将其称为“CounterContainer”,其中“<Counter>”是默认Blazor项目模板中的计数器组件。
@if(CounterIsVisible)
{
<Counter @ref="@_Counter" @key="@("CounterKey")" />
}
<button @onclick="() => CounterIsVisible = !CounterIsVisible">
Show/Hide counter
</button>
@code{
[Parameter] public Counter _Counter { get; set; }
private bool CounterIsVisible { get; set; } = true;
}
@if(计数器可见)
{
}
显示/隐藏计数器
@代码{
[参数]公共计数器_计数器{get;set;}
私有布尔计数器可见{get;set;}=true;
}
我想保存\u计数器
实例,以便查看我计数到的正确的\u计数器.currentCount
。我可以用一种方法保存它,但我发现它们都不实用,因为
- 我正在构建的组件包含的数据远不止一个变量
- 只要
存在并且仅用于可视化,我就需要这些数据计数器容器
- 这对于我的用例来说太复杂了
计数器
参考。我只是想查看它,而不是重新插入它并覆盖整个内容
希望这能让它更清楚一点(:我很惊讶它会编译,因为您的组件类拼写错误:
[Parameter] public **InnerCopmonent** _InnerComponent { get; set; }
为什么您的InnerComponent有一个@ref?InnerComponent做什么,为什么要引用它?您可以共享该组件的代码吗?我很惊讶它会编译,因为您拼写错了组件类:
[Parameter] public **InnerCopmonent** _InnerComponent { get; set; }
为什么您的InnerComponent有一个@ref?InnerComponent做什么?为什么您想引用它?您能共享该组件的代码吗?- 最佳选择:分离视图和数据。要保留的状态不应保留在组件内部,而应保留在单独的(ViewModel)对象中
- 简短的解决方案:始终呈现组件。使用@isVisible打开/关闭css类以隐藏它
- 最佳选择:分离视图和数据。要保留的状态不应保留在组件内部,而应保留在单独的(ViewModel)对象中
- 简短的解决方案:始终呈现组件。使用@isVisible打开/关闭css类以隐藏它
参数传递给子类。因为类是通过引用传递的,所以我不需要担心事件或类似的事情。(我只是为演示创建了一个类,以显示您可以在其中拥有任何想要的内容)
CounterData.cs
public class CounterData
{
public int counter { get; set; }
public string Title { get; set; } = "Counter";
public List<int> CounterHistory { get; set; } = new List<int>();
}
公共类计数器数据
{
公共int计数器{get;set;}
公共字符串标题{get;set;}=“Counter”;
公共列表计数器历史记录{get;set;}=new List();
}
反容器剃须刀
@page "/counter"
<h3>Counter Container</h3>
<button @onclick="()=> ShowCounter=!ShowCounter">Toggle</button>
@if (ShowCounter)
{
<Counter CarryingInstance="PersistentData" />
}
@code {
CounterData PersistentData = new CounterData();
bool ShowCounter = false;
}
<h3>@CarryingInstance.Title</h3>
<input @bind="CarryingInstance.Title" /><br />
<button @onclick="()=> Increment(1)">Add</button>
<button @onclick="()=>Increment(-1)">Sub</button>
@CarryingInstance.counter <br />
History:
@foreach (var item in CarryingInstance.CounterHistory)
{
<span> @item</span>
}
@code {
[Parameter]
public CounterData CarryingInstance { get; set; }
void Increment (int amount)
{
CarryingInstance.counter += amount;
CarryingInstance.CounterHistory.Add(CarryingInstance.counter);
}
}
@page”/counter
柜台集装箱
切换
@if(显示计数器)
{
}
@代码{
CounterData PersistentData=新的CounterData();
bool ShowCounter=false;
}
计数器.剃须刀
@page "/counter"
<h3>Counter Container</h3>
<button @onclick="()=> ShowCounter=!ShowCounter">Toggle</button>
@if (ShowCounter)
{
<Counter CarryingInstance="PersistentData" />
}
@code {
CounterData PersistentData = new CounterData();
bool ShowCounter = false;
}
<h3>@CarryingInstance.Title</h3>
<input @bind="CarryingInstance.Title" /><br />
<button @onclick="()=> Increment(1)">Add</button>
<button @onclick="()=>Increment(-1)">Sub</button>
@CarryingInstance.counter <br />
History:
@foreach (var item in CarryingInstance.CounterHistory)
{
<span> @item</span>
}
@code {
[Parameter]
public CounterData CarryingInstance { get; set; }
void Increment (int amount)
{
CarryingInstance.counter += amount;
CarryingInstance.CounterHistory.Add(CarryingInstance.counter);
}
}
@carringinstance.Title
添加
附属的
@carryngInstance.counter
历史:
@foreach(CarryingInstance.CounterHistory中的var项)
{
@项目
}
@代码{
[参数]
公共计数器数据携带实例{get;set;}
无效增量(整数金额)
{
结转实例.计数器+=金额;
CarryingInstance.CounterHistory.Add(CarryingInstance.counter);
}
}
我喜欢做这种事情的方式是创建一个承载类,我在父类中实例化该类,并将其作为参数传递给子类。由于类是通过引用传递的,所以我不需要担心事件或类似的事情。(我只是为演示创建了一个类,以显示您可以在其中拥有任何想要的内容)
CounterData.cs
public class CounterData
{
public int counter { get; set; }
public string Title { get; set; } = "Counter";
public List<int> CounterHistory { get; set; } = new List<int>();
}
公共类计数器数据
{
公共int计数器{get;set;}
公共字符串标题{get;set;}=“Counter”;
公共列表计数器历史记录{get;set;}=new List();
}
反容器剃须刀
@page "/counter"
<h3>Counter Container</h3>
<button @onclick="()=> ShowCounter=!ShowCounter">Toggle</button>
@if (ShowCounter)
{
<Counter CarryingInstance="PersistentData" />
}
@code {
CounterData PersistentData = new CounterData();
bool ShowCounter = false;
}
<h3>@CarryingInstance.Title</h3>
<input @bind="CarryingInstance.Title" /><br />
<button @onclick="()=> Increment(1)">Add</button>
<button @onclick="()=>Increment(-1)">Sub</button>
@CarryingInstance.counter <br />
History:
@foreach (var item in CarryingInstance.CounterHistory)
{
<span> @item</span>
}
@code {
[Parameter]
public CounterData CarryingInstance { get; set; }
void Increment (int amount)
{
CarryingInstance.counter += amount;
CarryingInstance.CounterHistory.Add(CarryingInstance.counter);
}
}
@page”/counter
柜台集装箱
切换
@if(显示计数器)
{
}
@代码{
CounterData PersistentData=新的CounterData();
bool ShowCounter=false;
}
计数器.剃须刀
@page "/counter"
<h3>Counter Container</h3>
<button @onclick="()=> ShowCounter=!ShowCounter">Toggle</button>
@if (ShowCounter)
{
<Counter CarryingInstance="PersistentData" />
}
@code {
CounterData PersistentData = new CounterData();
bool ShowCounter = false;
}
<h3>@CarryingInstance.Title</h3>
<input @bind="CarryingInstance.Title" /><br />
<button @onclick="()=> Increment(1)">Add</button>
<button @onclick="()=>Increment(-1)">Sub</button>
@CarryingInstance.counter <br />
History:
@foreach (var item in CarryingInstance.CounterHistory)
{
<span> @item</span>
}
@code {
[Parameter]
public CounterData CarryingInstance { get; set; }
void Increment (int amount)
{
CarryingInstance.counter += amount;
CarryingInstance.CounterHistory.Add(CarryingInstance.counter);
}
}
@carringinstance.Title
添加
附属的
@carryngInstance.counter
历史:
@foreach(CarryingInstance.CounterHistory中的var项)
{
@项目
}
@代码{
[参数]
公共计数器数据携带实例{get;set;}
无效增量(整数金额)
{
结转实例.计数器+=金额;
CarryingInstance.CounterHistory.Add(CarryingInstance.counter);
}
}
我已经看到了使用CSS隐藏组件的选项,以及它可能导致的意外问题,因为组件在合法地重新请求/重新实例化时不会经历正常的生命周期事件。因此,我正忙于更新几个组件以解决这一问题。我的建议是尽可能避免这样做。
另一种方法,类似于BennyBoys的携带实例方法,可能是通过利用依赖项注入,将类型注册为作用域服务或单例服务,并将其注入组件中
你可以在Chris Sainty的博客上阅读关于blazor中不同注册的工作方式及其行为,以及它是否符合你的需要
我会通过官方文档再次检查,虽然只是以防万一,但它们仍然以相同的方式运行,但这可能是一个很好的方法。我认为这取决于您的实际用例,即这样做是否是一个好主意,但这是另一个选项:)我看到了隐藏