【问题标题】:Why a Blazor WebAssembly @foreach{} can't render a list?为什么 Blazor WebAssembly @foreach{} 无法呈现列表?
【发布时间】:2021-02-01 01:41:33
【问题描述】:

我不明白为什么这个列表渲染不起作用,不再抛出一个奇怪的异常:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] 未处理的异常渲染组件:可空对象必须有值。 System.InvalidOperationException:可空对象必须有一个值。 在 System.Nullable`1[T].get_Value () in :0 在 C:\Users\vOId\Desktop\projects\Client\Components\Threads.razor 中的 .Client.Components.Threads.BuildRenderTree (Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) [0x010c7]: 106 在 Microsoft.AspNetCore.Components.ComponentBase.<.ctor>b__6_0(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder 构建器) 在:0 在 Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(Microsoft.AspNetCore.Components.Rendering.RenderBatchBuilder batchBuilder,Microsoft.AspNetCore.Components.RenderFragment renderFragment) 在:0 在 Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch (Microsoft.AspNetCore.Components.Rendering.RenderQueueEntry renderQueueEntry) 在:0 在 Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue () in :0

列表的初始化是正常的,从服务器获取数据e添加到列表中渲染(ViewThreads):

protected async override Task OnInitializedAsync()
{
    var result = await ThreadService.GetThreads();
    if (result.IsValid)
        ViewThreads.AddRange((List<ViewThread>)result.Data);
    //...
}

同时在@foreach的第一条指令的渲染点,异常的第106行,这就是渲染

//...
@foreach (var thread in ViewThreads)
{
    <p class="button is-light is-rounded neoFile petite-caps mb-3 @(CurrentThread != null && CurrentThread.Id == thread.Id ? "isSelected" : null)"
            @onclick="() => SelectThread(thread)" @key="thread">
        @thread.Title
    </p>
}
//...

这部分代码没有改变,只是列表的呈现突然抛出了该异常并且元素不再呈现。

可能是什么? 有没有人遇到过类似的问题?

【问题讨论】:

  • 贴出 ViewThread 类以及所有使用它的地方。对其他任何地方的可空属性或变量要非常明确。
  • 我在渲染部分中我能想到的每个配置都尝试了 null。我无法得到同样的错误。

标签: c# razor blazor blazor-webassembly


【解决方案1】:

初始化ViewThreads对象:

public List<ViewThread> ViewThreads { get; set; } = new List<ViewThread>();

或将foreach 包裹在if (ViewThreads != null) 周围:

if (ViewThreads != null)
{
    @foreach (var thread in ViewThreads)
    {
        <p class="button is-light is-rounded neoFile petite-caps mb-3 @(CurrentThread != null && CurrentThread.Id == thread.Id ? "isSelected" : null)"
            @onclick="() => SelectThread(thread)" @key="thread">
            @thread.Title
        </p>
    }
}

【讨论】:

  • 列表总是像在项目中那样初始化,我已经尝试过 if,但接收仍然存在
  • 要使 AddRange() 工作,必须预先初始化 ViewThreads 列表。
【解决方案2】:

可空对象必须有一个值。

您在此处发布的代码不会产生该错误。正如您自己所说,“这部分代码没有改变”

所以在某些方面你用... 替换了。寻找可以为空的属性。

并且“突然渲染该列表正在抛出”很可能是由数据引起的。某些列在您没想到的地方潜入了一个空值。

【讨论】:

  • 我发现答案和我的解决方案在中间,剃刀页面中有可以为空的实体,但尽管使用?(作为可空运算符)管理这些实体,但这还不够为了防止对这些对象的属性进行不正确的调用,所以我去掉了内联逻辑(如@(condition ? something : somethingElse))并将所有内容都设为解析变量,如protected string IsSomething =&gt; condition ? something : somethingElse;,这样做我绝对摆脱了那个异常(尽管调试仍在痛苦,因为没有足够的异常数据)。
猜你喜欢
  • 1970-01-01
  • 2020-09-15
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 2021-07-15
  • 2022-08-02
  • 2021-04-07
  • 2021-08-30
相关资源
最近更新 更多