Передать дочерний компонент как параметр в Blazor - PullRequest
1 голос
/ 02 ноября 2019

Я хотел бы сделать в Blazor то, что я обычно делаю в React: создать повторно используемый компонент, который внутренне использует другие дочерние компоненты, с возможностью передачи этих дочерних компонентов в качестве параметров. Мне нужно, чтобы иметь возможность обрабатывать дочерние компоненты как зависимость, которая может быть внедрена по требованию с любой пользовательской реализацией, которая может потребоваться в различных контекстах.

Представьте, например, компонент TextBox.razor, который дает вамвозможность передавать пользовательский компонент для отображения метки так, как вы хотите, при условии, что он реализует интерфейс ILabel. Я пытался что-то вроде этого, но синтаксис, кажется, не является действительным:

TextBox.razor

enter image description here

Как вы видите изна скриншоте Blazor не позволяет мне использовать параметр Label в качестве компонента. Есть идеи, как этого добиться?

1 Ответ

0 голосов
/ 02 ноября 2019

Вы должны быть в состоянии сделать это с помощью шаблонных компонентов.

Textbox.razor

@typeparam inputType
<div class="textbox">
    @if(LabelTemplate!=null && TItem!=null)
        @LabelTemplate(TItem)
    <input type="text"/>
</div>


    @code{
        [Parameter]
        public RenderFragment<inputType> LabelTemplate { get; set; }
        [Parameter]
        public inputType TItem { get; set; }
    }

В приведенном выше коде вы указываете, что компонент принимает тип, используя @typeparam inputType, и получает объект этого типа в качестве параметра TItem.

Вы также принимаете LabelTemplate, который принимает объект типа inputType. Чтобы отобразить этот фрагмент, мы вызываем @LabelTemplate и передаем наш параметр TItem.

Теперь давайте посмотрим, как использовать наш шаблонный компонент в новом компоненте с именем PersonForm.razor

PersonForm.razor

<Textbox TItem="myPerson">
    <LabelTemplate>
        @context.Name
    </LabelTemplate>
</Textbox>
<Textbox TItem="myPerson">
    <LabelTemplate>
        @context.PhoneNumber
    </LabelTemplate>
</Textbox>

@code{

  Person myPerson = new Person { Name = "Jane Doe", PhoneNumber = "999 999 9999" };
    public class Person
    {
        public string Name { get; set; }
        public string PhoneNumber { get; set; }
    }
}

Я передаю свой объект Personк свойству TItem каждого компонента Textbox и доступу к нему в шаблоне LabelTemplate с использованием синтаксиса @context.

Поначалу это может показаться запутанным, поэтому, пожалуйста, прочтите это здесь

Отредактировано Это зависит только от того, чего вы хотите достичь. С подробным синтаксисом обеспечивается гибкость на стороне «реализации» компонента. Вместо форсирования интерфейса, который может не работать с широким спектром моделей / классов, вы позволяете реализации указывать, что делать.

Если вы хотите что-то менее подробное / более жесткое, вы также можете сделать следующее.

@implements ILabel 
<div class="textbox"> 
    <label>@Text</label> 
    <input type="text"/> 
</div> 
@code
{ 
    [Parameter] 
    public string Text { get; set; } 
} 

ILabel.cs

    public interface ILabel
    {
        string Text { get; set; }
    }

...