Отправить некоторые данные из дочернего компонента в родительский компонент перед рендерингом в blazor

#c# #blazor

#c# #blazor

Вопрос:

я пытаюсь создать дочерний компонент, который отправляет некоторые данные в ParentComponent до того, как Parent отобразит себя. Сначала я пытаюсь отправить ссылку на родительский компонент всем дочерним компонентам, а затем пытаюсь установить простой текст в 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;
            
        }

    }
  

Ответ №1:

создайте дочерний компонент, который отправляет некоторые данные в 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; }

}
  

Дочерний компонент.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;

    }
}
  

Скопируйте и запустите этот код. Обратите внимание, что текст в свойстве text не изменится. Он всегда будет отображать строку «blaaaa». Решение этой проблемы заключается в использовании EventCallback для передачи нового значения свойству Text, а также для повторного рендеринга родительского компонента.

Вообще говоря, использование компонента CascadingValue не подходит. И вы не должны передавать ссылку на родительский компонент дочернему компоненту. Обычно вы должны использовать параметры и события компонента (EventCallback ‘delegate’) для обработки отношений между родительским и дочерним компонентами

Ответ №2:

Вы не можете напрямую отображать дочерний компонент внутри parentcomponent. Вместо этого вам нужно использовать параметры шаблона, шаблонный компонент определяется путем указания одного или нескольких параметров компонента типа RenderFragment или RenderFragment . Фрагмент рендеринга представляет собой сегмент пользовательского интерфейса для рендеринга. RenderFragment принимает параметр типа, который может быть указан при вызове фрагмента рендеринга. что-то вроде этого :

 @typeparam TItem

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

@code {

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

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

}

параметры шаблона могут быть указаны с использованием дочерних элементов, которые соответствуют именам параметров. взгляните на документ Microsoft