Проблема с шаблоном / рендерингом дочернего компонента Blazor - PullRequest
0 голосов
/ 05 октября 2019

У меня есть странность с шаблонными компонентами Blazor, по которым я ищу руководство.

У меня есть два компонента, один называется DataTable, а другой - DataModal. Оба принимают универсальный TItem в качестве параметра типа для визуализации таблицы элементов с использованием фрагментов рендеринга для разметки.

DataTable отображает таблицу HTML, а DataModal - это модальная оболочка начальной загрузки, которая содержит компонент DataTable в качестве дочернего компонента. ,Идея состоит в том, чтобы показать модальное диалоговое окно с таблицей данных для выбора пользователя.

Когда компонент DataTable используется сам по себе как часть компонента страницы, он работает нормально. Когда используется компонент DataModal, передавая ту же коллекцию элементов (как TItem) и ту же разметку фрагмента рендеринга, я не получаю правильное содержимое в DataTable. Вместо этого я получаю фрагмент и имя сборки TItem для того же количества элементов.

Это разметка для компонента таблицы данных, встроенного в страницу:

<DataTable TItem="TicketSummaryModel" PageNumberChanged="OnPageChanged" Class="table table-hover table-striped dataTable responsive no-footer" RowClicked="@OnRowClicked" Items="SearchedTickets.Data"
                                   TotalRecords="@SearchedTickets.RecordsTotal" TotalPages="SearchedTickets.PagesTotal">
   <DataTableHeader>
       <th>Ticket Number</th>
       <th>Updated On</th>
       <th>Title</th>
       <th>Created By</th>
       <th>Category</th>
       <th>Status</th>
   </DataTableHeader>
   <DataRowTemplate>
       <td><i class="fas fa-circle mr-1 @context.PriorityClass"></i> @context.TicketNumber</td>
       <td>@context.UpdatedOn</td>
       <td>@context.Title</td>
       <td>@context.CreatedByUser</td>
       <td>@context.Category</td>
       <td><i class="fas fa-square mr-1 @context.StatusClass"></i> @context.Status</td>
    </DataRowTemplate>

Это выводит правильно, каждое свойство во фрагменте рендеринга правильно отображается как элемент внутри таблицы.

Когда я делаю то же самое с компонентом DataModal внутри страницы, возникает проблема:

<DataModal @ref="modalRef" TitleClass="bg-primary" ModalSize="ModalSize.ExtraLarge" Title="Test Modal" Items="@SearchedTickets.Data"
                   TitleIcon="fa-check" TItem="TicketSummaryModel" TableClass="table table-hover table-striped dataTable responsive no-footer"
                   TotalRecords="@SearchedTickets.RecordsTotal" TotalPages="SearchedTickets.PagesTotal">
            <DataTableHeader>
                <th>Ticket Number</th>
                <th>Updated On</th>
                <th>Title</th>
                <th>Created By</th>
                <th>Category</th>
                <th>Status</th>
            </DataTableHeader>
            <DataRowTemplate>
                <td><i class="fas fa-circle mr-1 @context.PriorityClass"></i> @context.TicketNumber</td>
                <td>@context.UpdatedOn</td>
                <td>@context.Title</td>
                <td>@context.CreatedByUser</td>
                <td>@context.Category</td>
                <td><i class="fas fa-square mr-1 @context.StatusClass"></i> @context.Status</td>
            </DataRowTemplate>
</DataModal>

Разметка компонента DataModal выглядит следующим образом:

@inherits DataModalBase<TItem>
@typeparam TItem

<Modal @ref="@ModalRef">
        <ModalContent Size="@ModalSize" IsCentered="true">
            <ModalHeader Class="@TitleClass">
                <ModalTitle>
                    @if (Title != null)
                    {
                        @if (TitleIcon != null)
                        {
                            <i class="@("fal " + TitleIcon) mr-2"></i>
                        }
                        @Title
                    }
                </ModalTitle>
                <CloseButton Clicked="Close" />
            </ModalHeader>
            <ModalBody>
                @if (Items != null)
                {
                    <DataTable TItem="TItem" Class="@TableClass" Items="@Items">
                        <DataTableHeader>
                            @DataTableHeader
                        </DataTableHeader>
                        <DataRowTemplate>
                            @DataRowTemplate
                        </DataRowTemplate>
                    </DataTable>
                }
                else
                {
                    <div class="mr-auto ml-auto mt-4 mb-4">
                        <div class="lds-hourglass"></div>
                    </div>
                }
            </ModalBody>
        </ModalContent>
</Modal>

Модал показывает таблицу, заголовки верны из фрагмента рендеринга DataTableHeader, а количество строк для данных элементов верное. Проблема в том, что вывод фрагмента рендеринга DataRowTemplate теперь представляет собой только имена сборок:

Microsoft.AspNetCore.Components.RenderFragment`1[MyProject.Models.Tickets.TicketSummaryModel]
Microsoft.AspNetCore.Components.RenderFragment`1[MyProject.Models.Tickets.TicketSummaryModel]
Microsoft.AspNetCore.Components.RenderFragment`1[MyProject.Models.Tickets.TicketSummaryModel]
Microsoft.AspNetCore.Components.RenderFragment`1[MyProject.Models.Tickets.TicketSummaryModel]
...

Есть идеи, почему это происходит? Как DataModal, так и DataTable используют одни и те же объявления для коллекции элементов для отображения:

[Parameter] public IEnumerable<TItem> Items { get; set; } // The data items
[Parameter] public RenderFragment<TItem> DataRowTemplate { get; set; } // The HTML markup for each row

DataTable отображает DataRowTemplate с использованием следующего кода, который снова работает, когда DataTable используется вне родительского элемента, ноне в детстве (внутри DataModal):

<tbody>
    @if (Items != null)
    {
        @foreach (var item in Items)
        {
            <tr @onclick="@(() => OnRowClicked(item))">@DataRowTemplate(item)</tr>
        }
    }
</tbody>

Если вам нужна дополнительная информация, чтобы помочь в этом вопросе, дайте мне знать.

...