【问题标题】:Send some data from child to parent component before render in blazor在 blazor 中渲染之前将一些数据从子组件发送到父组件
【发布时间】:2021-02-28 07:32:02
【问题描述】:

我正在尝试创建一个 ChildComponent,它会在 Parent 呈现自身之前向 ParentComponent 发送一些数据。 首先,我尝试将 Parent 的引用发送给所有 ChildComponents,然后尝试使用参数值直接从 Childs 中设置 ParentComponent 中的简单文本。 有人可以告诉我,为什么下面的代码不起作用? 感谢大家的帮助!

主文件:

@page "/test"

<h3>TestTabeli</h3>
<ParentComponent>
    <ChildComponent Name="Child nr 1" />
    <ChildComponent Name="Child nr 2" />
</ParentComponent>

父文件:

<h3>ParentComponent</h3>

<CascadingValue Value="Parent" Name="ParentRef">
    @body
</CascadingValue>

<br />
<p>My Childrens: @text</p>

@code {
    public string text { get; set; } = "blaaaa";
    public ParentComponent Parent { get; set; }

    protected override void OnInitialized()
        {
        base.OnInitialized();
        Parent = this;
        }
    public RenderFragment body { get; set; }

    }

子组件:

<h3>ChildComponent</h3>

@code {
    [Parameter]
    public string Name { get; set; } = "Child Name";

    [CascadingParameter(Name = "ParentRef")]
    public ParentComponent parent { get; set; }

    protected override void OnParametersSet()
        {
        base.OnParametersSet();
        parent.text += "<br /> Hi! My name is: " + Name;
            
        }

    }

【问题讨论】:

    标签: c# blazor


    【解决方案1】:

    创建一个 ChildComponent 在 Parent 之前向 ParentComponent 发送一些数据 会自己渲染

    这是不可能的。女人在出生前能生孩子吗?但是你稍后会看到,我们可以欺骗人眼相信这是可能的。但是您的问题是您的代码无法正常工作的原因,对吧?

    <CascadingValue Value="Parent" Name="ParentRef">
        @body
    </CascadingValue>
    

    这是您的代码无法执行的第一个原因。您必须使用 @ChildContent 而不是 @body

    你也应该在代码中包含这个:

    [Parameter]
    public RenderFragment ChildContent { get; set; }
    

    请注意,您必须添加 [Parameter] 属性。

    对您的代码进行一些额外的更改后,它可能会起作用:

    ParentComponent.razor

    @page "/ParentComponent"
    
    <h3>ParentComponent</h3>
    
    <CascadingValue Value="this" Name="ParentRef">
        @ChildContent
    </CascadingValue>
    
    <br />
    <p>My Childrens: @text</p>
    
    @code {
        public string text { get; set; } = "blaaaa";
      //  public ParentComponent Parent { get; set; }
    
        protected override void OnInitialized()
        {
            base.OnInitialized();
          //  Parent = this;
        }
        [Parameter]
        public RenderFragment ChildContent { get; set; }
    
    }
    

    ChildComponent.razor

    <h3>@Name</h3>
    
    @code {
        [Parameter]
        public string Name { get; set; } = "Child Name";
    
        [CascadingParameter(Name = "ParentRef")]
        public ParentComponent parent { get; set; }
    
        protected override void OnParametersSet()
        {
             parent.text += "Hi! My name is: " + Name;
    
        }
    }
    

    复制并运行该代码。请注意,文本属性中的文本不会更改。它总是显示字符串“blaaaa”。解决方案是使用 EventCallback 将新值传递给 Text 属性以及重新渲染父组件。

    一般来说,使用 CascadingValue 组件是不合适的。并且您不应该将对父组件的引用传递给子组件。通常应该使用组件参数和事件(EventCallback 'delegate')来处理父子关系

    【讨论】:

      【解决方案2】:

      你不能直接在父组件中渲染子组件。相反,您需要使用模板参数,模板化组件是通过指定一个或多个 RenderFragment 或 RenderFragment 类型的组件参数来定义的。渲染片段表示要渲染的一段 UI。 RenderFragment 采用可以在调用渲染片段时指定的类型参数。像这样:

      @typeparam TItem
      
          @foreach (var item in Items)
          {
             @ChildTemplate(item)
          }
      

      @代码 {

      [Parameter]
      public RenderFragment<TItem> ChildTemplate { get; set; }
      
      [Parameter]
      public IReadOnlyList<TItem> Items { get; set; }
      

      }

      可以使用与参数名称匹配的子元素来指定模板参数。 看看Microsoft Document

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-13
        • 1970-01-01
        • 1970-01-01
        • 2020-09-28
        • 2020-07-29
        • 2019-09-07
        • 2018-07-07
        相关资源
        最近更新 更多