Динамически визуализировать неизвестный экземпляр компонента со значениями свойств в Blazor (не дочерний / родительский)? - PullRequest
0 голосов
/ 29 февраля 2020

Короткий вопрос: есть ли способ визуализировать уже созданный экземпляр Экземпляр компонента?

Я хочу иметь динамическое диалоговое окно c содержимого, и содержимое должно быть создано с использованием класса Component и они также могут иметь пользовательские свойства, атрибуты и т. д. c.


У меня есть следующая структура Blazor, где все в MainComponent и Dialog разделены, но могут связываться друг с другом, используя IDialogService:

<main>
    <MainComponent />
</main>

<Dialog />

Однако я хочу, чтобы содержимое внутри Dialog.razor было динамическим c, поэтому я пытаюсь это сделать:

<dialog data-active="@(this.IsShowing)">
    <dialog-cover></dialog-cover>

    <dialog-container>
        @if (this.contentFragment != null)
        {
            @(this.contentFragment)
        }
    </dialog-container>
</dialog>

@code {

    RenderFragment contentFragment { get; set; }

    internal void SetFragments(ComponentBase dialog)
    {
        this.contentFragment = builder =>
        {
            builder.OpenComponent(0, dialog.GetType());
            builder.CloseComponent();
        };

        this.StateHasChanged();
    }

    // Other logic code for showing/hiding etc

}

Это работает, пока я передаю "простой" компонент там, однако, я хочу некоторый динамический c текст, например, ConfirmDialog.razor:

@if (this.Title != null)
{
    <header>
        <h2>@(this.Title)</h2>
    </header>
}

@if (this.Text != null)
{
    <main>
        @(this.Text)
    </main>
}

@code {

    public string Title { get; set; }
    public string Text { get; set; }

}

Использование:

    var diagConfirm = new ConfirmDialog()
    {
        Title = "Please confirm!",
        Text = "Something good happened!",
    };

    var result = await this.dialogService.ShowAsync(diagConfirm);

Однако, используя фрагмент вместо этого создается новый экземпляр ConfirmDialog, а diagConfirm не используется. В любом случае использовать экземпляр вместо просто имя класса компонента?

1 Ответ

0 голосов
/ 29 февраля 2020

Это временное решение, которое я сейчас использую. Я знаю, что это взлом и не должен быть правильным ответом, но пока он работает.

        var properties = component.GetType().GetProperties();

        RenderFragment fragment = builder =>
        {
            builder.OpenComponent(0, component.GetType());

            foreach (var property in properties)
            {
                if (property.GetCustomAttribute<ParameterAttribute>() == null)
                {
                    continue;
                }

                var value = property.GetValue(component);

                builder.AddAttribute(0, property.Name, value);
            }

            builder.CloseComponent();
        };

По сути, я использую Reflection, чтобы скопировать все свойства с Parameter во вновь созданный Компонент. Для этого в свойствах компонента должны быть прикреплены атрибуты [Parameter].

В этой строке вы также будете получать предупреждения от VS, но вы можете спокойно их игнорировать, если знаете, что делаете.

    var diagConfirm = new LConfirmDialog()
    {
        Title = "Title",
        Text = "Hello",
    };

Параметр компонента «Заголовок» нельзя устанавливать вне его компонента

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...