Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Blazor中保留组件实例_C#_Asp.net Core_Blazor - Fatal编程技术网

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>&nbsp; @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>&nbsp; @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>&nbsp; @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>&nbsp; @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中不同注册的工作方式及其行为,以及它是否符合你的需要


      我会通过官方文档再次检查,虽然只是以防万一,但它们仍然以相同的方式运行,但这可能是一个很好的方法。我认为这取决于您的实际用例,即这样做是否是一个好主意,但这是另一个选项:)

      我看到了隐藏