【问题标题】:Blazor 3.2 Component is throwing a null reference exception on childBlazor 3.2 组件在子级上引发空引用异常
【发布时间】:2020-09-06 01:18:06
【问题描述】:

我正在尝试制作一个类似于https://docs.microsoft.com/en-us/aspnet/core/blazor/templated-components?view=aspnetcore-3.1 中的 blazor 模板化组件,但带有一个嵌套子表。

父表按预期工作,但在 ChildRowTemplate 的绑定上引发了 null ref 异常(在附加代码中突出显示)。该模型是一代理多复合体。

模板

 @typeparam TItem

<table>
<thead>
    <tr>@TableHeader</tr>
</thead>
<tbody>
    @foreach (var item in Items)
    {
        <tr> The error 
            @if (OnCollapse.HasDelegate)
            {
                <td>
                    <button class="primary-button mb-1" @onclick="@(_=>HandleCollapse(item))">Toggle Complexes</button>
                </td>
            }  
            @RowTemplate(item)
        </tr>
        <tr>
            @ChildRowTemplate(item)
        </tr>
    }
</tbody>
<tfoot>
    <tr>@TableFooter</tr>
</tfoot>
</table>

 @code {

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

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

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

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

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

[Parameter]
public EventCallback<object> OnCollapse { get; set; }

   void HandleCollapse(TItem item)
   {
      OnCollapse.InvokeAsync(item);
   }
}

代码

<TableTemplate Items="@Agents" OnCollapse="toggle" Context="agent">
        <TableHeader>
            <th><button class="outline-button">Add Agent</button></th>
            <th>Co. Name</th>
            <th>Co. Number</th>
            <th>Admin</th>
            <th>Admin Email</th>
            <th>Admin Phone</th>
        </TableHeader>
        <RowTemplate>
            <td>@agent.CompanyName</td>
            <td>@agent.CompanyNumber</td>
            <td>@agent.AdminFirstName @agent.AdminLastName</td>
            <td>@agent.AdminEmail</td>
            <td>@agent.AdminPhoneNumber</td>
        </RowTemplate>
        <ChildRowTemplate Context="agent">
            <TableTemplate Items="@agent.Complexes"> @*<--- NULL REF *@ 
                <TableHeader>
                    <th>Complex Name</th>
                    <th>Is Active</th>
                    <th>Address</th>
                </TableHeader>
                <RowTemplate Context="complex">
                    <td>@complex.Name</td>
                    <td>@complex.IsActive</td>
                    <td>@complex.DisplayAddress</td>
                </RowTemplate>
            </TableTemplate>
        </ChildRowTemplate>
        <TableFooter></TableFooter>
    </TableTemplate>

【问题讨论】:

  • 您对所有代理的agent.Complexes != null 有多大把握?
  • 完全确定。

标签: asp.net-core blazor


【解决方案1】:

我能够重现您的错误,并且据我所知发现了问题。它源于您的表格模板如何处理ChildRowTemplate 片段。

首先,为了澄清,我模拟了一些数据来提供我页面后面代码中的表格,如下所示。这确保了我的嵌套数据没有空值,正如您在评论中指出的那样,您知道您的 agent.Complexes 属性中没有空值。

@code {

    public List<ListItem> Items { get; set; } = new List<ListItem>();

    protected override async Task OnInitializedAsync()
    {
        for (var i = 1; i < 4; i++)
        {
            Items.Add(new ListItem()
            {
                Name = $"List Item #{i}",
                NestedItems = new List<NestedItem>()
            });

            foreach (var item in Items)
            {
                for (var j = 1; j < 4; j++)
                {
                    item.NestedItems.Add(new NestedItem()
                    {
                        Name = $"Item {i} contains nested item {j}"
                    });
                }
            }
        }
    }

    public class ListItem
    {
        public string Name { get; set; }

        public List<NestedItem> NestedItems { get; set; }
    }

    public class NestedItem
    {
        public string Name { get; set; }
    }
}

然后我按照您的方式设置表格,但实际表格结构要简单一些,然后运行应用程序。就像你有的空引用异常。错误重现。

<TableTemplate Items="Items" Context="item">
    <TableHeader>
        <th>Item Name</th>
    </TableHeader>
    <RowTemplate>
        <tr>@item.Name</tr>
    </RowTemplate>
    <ChildRowTemplate>
        <TableTemplate Items="item.NestedItems" Context="nestItem">
            <TableHeader>
                <th>Nested Item Name</th>
            </TableHeader>
            <RowTemplate>
                <tr>@nestItem.Name</tr>
            </RowTemplate>
        </TableTemplate>
    </ChildRowTemplate>
    <TableFooter></TableFooter>
</TableTemplate>

然后,我在模板组件中添加了一个空检查来处理您不设置 ChildRowTemplateComponent 的情况,因此它仅在有要渲染的内容时才渲染,如下所示:

.....
<tbody>
    @foreach (var item in Items)
    {
        <tr>
            @if (OnCollapse.HasDelegate)
            {
                <td>
                    <button class="primary-button mb-1" @onclick="@(_=>HandleCollapse(item))">Toggle Complexes</button>
                </td>
            }
            @RowTemplate(item)
        </tr>
        @if (ChildRowTemplate != null) @*<<<<< Note the null check!*@
        {
            <tr>
                <td>@ChildRowTemplate(item)</td>
            </tr>
        }
    }
</tbody>
....

运行应用程序,没有更多例外。表格需要调整和设置样式,但您已经知道,这将使应用程序按预期运行。

希望这会有所帮助!

【讨论】:

  • 感谢 Nik - 我不再使用模板组件,直到获得更好的理解,但很快就会回复它们。您的更新很有意义。
猜你喜欢
  • 2021-05-29
  • 2016-02-28
  • 1970-01-01
  • 1970-01-01
  • 2014-08-31
  • 2018-06-17
  • 2021-12-14
  • 1970-01-01
  • 2019-09-15
相关资源
最近更新 更多