【问题标题】:How to invoke Blazor child component from parent component如何从父组件调用 Blazor 子组件
【发布时间】:2022-12-22 22:22:12
【问题描述】:

我在将一些旧代码迁移到 Blazor 时遇到了一个独特的情况。例如,以下代码将包含在“ComponentTest.razor”页面中。我想通过 ComponentTest.razor 中的代码访问 ParentComponent 及其参数以及 ChildComponent 及其参数。在这种情况下,ParentComponent 由包含页面“ComponentTest.razor”调用,但 ChildComponents 不可访问,甚至似乎不可访问。

<ParentComponent PParam1="pValue1" PParam2="pValue2" PParam3="pValue3"> 
    <ChildComponent CParm1="cvalue1" CParm2="cvalue1"/>
    <ChildComponent CParm1="cvalue2" CParm2="cvalue2"/>
    <ChildComponent CParm1="cvalue3" CParm2="cvalue3"/>
    <ChildComponent CParm1="cvalue4" CParm2="cvalue4"/>
</ParentComponent>

是的,通常 ChildComponent 会被放置在 ParentComponent.razor 文件中,这工作正常,但那不是我遇到的情况。似乎有一种方法可以使用 RenderTreeBuilder 来访问子组件,但我不知道如何调用它们,因此它们的 OnInitialized 会执行并设置参数。

【问题讨论】:

  • 在我回答之前——ChildComponent 对象的数量是设置为四个,还是来自可变长度的数据集?我会以不同的方式对待这些情况。您真的需要使用内部标记来定义此页面上的 ChildComponent 对象吗?
  • ChildComponent 的数量会有所不同。我确实需要使用内部标记来获取在 ChildComponent 上指定的参数。
  • “获取参数”是什么意思?价值观从何而来?如果它们来自数据列表,您应该将列表传递给父级,并循环访问那里的数据,而不是像这样使用标记。

标签: blazor blazor-webassembly asp.net-blazor


【解决方案1】:

您需要对设置进行一些更改才能访问父级中的子组件 这是你的完整代码

父组件.razor

<CascadingValue Value="@this" IsFixed="true">
    <div>
    </div>
</CascadingValue>

包含所有子组件的子组件列表

private List<ChildComponent> items = new();

每次在父组件中创建时,子组件都会调用此方法

internal void Register(ChildComponent item)
{
    this.items.Add(item);               
}

每次释放子组件时,子组件都会调用此方法

internal void Unregister(ChildComponent item)
{
    this.items.Remove(item);
}

这是您的子组件

此代码可以访问其父组件

[CascadingParameter]
protected ParentComponent Context { get; set; }

创建任何子组件时,它都会在其父组件中注册自己

protected override void OnInitialized()
{
    Context?.Register(this);
}

这就是子组件在处理时从父组件中注销的方式

public void Dispose()
{
    Context?.Unregister(this);
}

在父组件中 通过使用您选择的列表操作进行上述设置,您可以访问所有子组件及其公共函数和父组件中的变量,例如

items.ForEach
items.Find

【讨论】:

    【解决方案2】:

    你有两个选择:

    1. 创建一个服务,然后将其注入到需要数据的每个组件中
    2. 使用级联的页面状态组件 - 如下所示。

      这是状态类:

      PageState

      public class PageState
      {
          public int Id { get; set; }
          public string? MyString { get; set; }
      }
      

      和组件: CascadingPageState

      <CascadingValue Value=this.State>
          @this.ChildContent
      </CascadingValue>
      
      @code {
          public readonly PageState = new PageState;
          [Parameter] public RenderFragment? ChildContent { get; set; }
      }
      

      并用于Index

      @page "/"
      <PageTitle>Index</PageTitle>
      `<CascadingPageState @ref=this.pageState>
          @*Any component can capture the cascade*@
          <Test />
      </CascadingPageState>
      <h1>Hello, world!</h1>
      
      Welcome to your new app.
      
      <SurveyPrompt Title="How is Blazor working for you?" />
      
      
      @code {
          private PageState? pageState;
      
          protected override void OnInitialized()
          {
              if (this.pageState is not null)
                  this.pageState.MyString = "Hello";
          }
      }
      

    【讨论】:

      猜你喜欢
      • 2020-05-19
      • 2021-06-10
      • 2021-07-04
      • 2019-11-15
      • 2019-06-23
      • 2022-11-23
      • 2021-05-02
      • 2020-04-01
      相关资源
      最近更新 更多