.net 计算或调用后Blazor渲染
在Blazor中迈出第一步 我的页面Test.razor有一个简单的网格:.net 计算或调用后Blazor渲染,.net,blazor,.net-5,.net,Blazor,.net 5,在Blazor中迈出第一步 我的页面Test.razor有一个简单的网格: <table class="table"> <thead> <tr>Message</tr> </thead> <tbody> @foreach (var exception in Exceptions) { <tr>exc
<table class="table">
<thead>
<tr>Message</tr>
</thead>
<tbody>
@foreach (var exception in Exceptions)
{
<tr>exception.Message</tr>
}
</tbody>
</table>
消息
@foreach(异常中的var异常)
{
例外消息
}
我的逻辑是:
公共部分类测试
{
public List<TestEventModel> Exceptions { get; set; }
protected override async void OnInitialized()
{
var exceptionsResponse = (await http.GetAsync("TestController")).Content.ReadAsStringAsync();
Exceptions = JsonConvert.DeserializeObject<List<TestEventModel>>(await exceptionsResponse);
}
}
{
公共列表异常{get;set;}
受保护的重写异步void OnInitialized()
{
var exceptionResponse=(wait http.GetAsync(“TestController”)).Content.ReadAsStringAsync();
Exceptions=JsonConvert.DeserializeObject(等待ExceptionResponse);
}
}
问题:未处理的异常呈现组件:对象引用未设置为对象的实例
线路上发生异常:
@foreach(异常中的var异常)
但根据生命周期,它应该仅在执行初始化后才开始渲染:
例如,如果我确实在构造函数中初始化了列表,问题就不存在了,但是列表当然是空的,并且不会显示http调用的结果。为什么不初始化异常?
async OnInitialized
(和OnInitializedAsync
;如果您正在执行HTTP请求之类的异步工作,则应使用此选项,而不是OnInitialized
)在呈现之前开始,但wait
取消阻止执行链,允许页面在资产之前呈现(即问题中的异常
)已加载
例子
我创建了一个测试页面,记录每个生命周期事件的时间顺序。特别要注意的是OnInitialized
方法:
protected override async void OnInitialized()
{
记录(“->OnInitialized”);
//注意:我不提倡你使用任务。运行。。。
//这是为了模拟对外部源的异步调用!
Data=wait Task.Run(()=>newlist{“Hello there”});
StateHasChanged();//并非总是必需的…请参阅下面的链接
base.OnInitialized();
记录(“初始化”);
base.OnInitialized();
记录(“为什么不初始化异常?
async OnInitialized
(和OnInitializedAsync
;如果您正在执行HTTP请求之类的异步工作,则应使用此选项,而不是OnInitialized
)在呈现之前开始,但wait
取消阻止执行链,允许页面在资产之前呈现(即问题中的异常
)已加载
例子
我创建了一个测试页面,记录每个生命周期事件的时间顺序。特别要注意OnInitialized
方法:
protected override async void OnInitialized()
{
记录(“->OnInitialized”);
//注意:我不提倡你使用任务。运行。。。
//这是为了模拟对外部源的异步调用!
Data=wait Task.Run(()=>newlist{“Hello there”});
StateHasChanged();//并非总是必需的…请参阅下面的链接
base.OnInitialized();
记录(“初始化”);
base.OnInitialized();
Record(“Blazor在多个过程中呈现,您所经历的是绝对正常的。我的理解是,即使页面等待异步数据填充(复杂的数据库搜索等),也会加载大部分页面
有两种方法可以避免在async init上抛出null引用:
1.检查空值。别担心,组件将初始化所有内容,并在第二遍正确渲染
@if (Exceptions is not null){
foreach (var exception in Exceptions)
{
<tr>exception.Message</tr>
}
}
Blazor在多个过程中呈现,您所体验到的是绝对正常的。我的理解是,即使页面等待异步数据填充(复杂的数据库搜索等),也会加载大部分页面
有两种方法可以避免在async init上抛出null引用:
1.检查空值。别担心,组件将初始化所有内容,并在第二遍正确渲染
@if (Exceptions is not null){
foreach (var exception in Exceptions)
{
<tr>exception.Message</tr>
}
}
至于你为什么要找
你打电话:
protected override async void OnInitialized()
{
var exceptionsResponse = (await http.GetAsync("TestController")).Content.ReadAsStringAsync();
}
OnInitialized
是OnInitializedAsync
的同步版本,应该只运行同步代码。您已将其转化为fire并忘记async void
事件处理程序
它同步运行,直到它遇到一些真正的生成代码-http.GetAsync
。在这一点上,它返回到组件SetParametersAsync
。这将运行到完成。当Exceptions=..
getrunSetParametersAsync
完成时,组件已完成渲染并出错原因异常
仍然为空
您需要在OnInitializedAsync()中运行代码。这会将任务返回到它可以等待的SetParametersAsync
,并且只有当OnInitializedAsync
通过返回已完成的任务完成时才会继续
protected override async Task OnInitializedAsync()
{
var exceptionsResponse = (await http.GetAsync("TestController")).Content.ReadAsStringAsync();
Exceptions = JsonConvert.DeserializeObject<List<TestEventModel>>(await exceptionsResponse);
}
当您在代码中调用statehaschange
时,您需要询问原因?原因是有道理的,但通常是为了从先前的编码错误中恢复过来。当您在寻找原因时
你打电话:
protected override async void OnInitialized()
{
var exceptionsResponse = (await http.GetAsync("TestController")).Content.ReadAsStringAsync();
}
OnInitialized
是OnInitializedAsync
的同步版本,应该只运行同步代码。您已将其转化为fire并忘记async void
事件处理程序
它同步运行,直到它遇到一些真正的生成代码-http.GetAsync
。在这一点上,它返回到组件SetParametersAsync
。这将运行到完成。当Exceptions=..
getrunSetParametersAsync
完成时,组件已完成渲染并出错原因异常
仍然为空
您需要在OnInitializedAsync()中运行代码。这会将任务返回到它可以等待的SetParametersAsync
,并且只有当OnInitializedAsync
通过返回
@foreach (var item in Items)
{
}
public List<string> Items { get; set; } = new();
protected override async Task OnInitializedAsync()
{
Console.WriteLine("OnInitializedAsync start");
await Task.Delay(100);
Console.WriteLine("OnInitializedAsync done");
Items = new List<string> { "aa", "bb", "cc", };
}
protected override Task OnAfterRenderAsync(bool firstRender)
{
Console.WriteLine($"OnAfterRenderAsync {firstRender}");
return base.OnAfterRenderAsync(firstRender);
}