我正在做一个blazor服务器端项目,我有一个组件,它被传递了一个模型(pickWeek)作为参数。我可以在html中使用模型,但OnInitializedAsync总是认为模型为空。
我曾将本地类型作为参数,从Page传入一个组件中,这种方式没有问题。我使用NullWeek作为默认参数,所以OnInitializedAsync中使用的数字只出现在NullWeek中。如果这与此有关,有一个兄弟组件通过.InvokeAsync调用将Week模型返回到页面,其中StateHasChanged()在更新后被调用。看起来新的Week正在问题组件上得到更新,但是OnInitializeAsync()要么没有看到它,要么就再也没有启动--这也许是我的问题,但我认为它不是这样工作的。
例如,下面的代码总是显示 "FAILURE",但它会显示正确的Week.Number。 下面的代码。
<div>@pickedWeek.Number</div>
@if(dataFromService != null)
{
<div>SUCCESS</div>
}
else
{
<div>FAILURE</div>
}
@code{
[Parameter]
public Week pickedWeek { get; set; }
protected IEnumerable<AnotherModel> dataFromService { get; set; }
protected override async Task OnInitializedAsync()
{
if (pickedWeek.Number > 0)
{
dataFromService = await _injectedService.MakeACall(pickedWeek.Id);
}
}
}
@robsta在评论中说的很对,你可以使用 "OnInitializedAsync"。OnParametersSet
为此,你会遇到另一个问题。然后,你会遇到另一个问题,因为每个reender会再次设置你的参数,并对你的服务产生另一个调用。我通过使用一个标志字段和 OnParametersSet
方法。试试这个方法,然后汇报一下。
private bool firstRender = true;
protected override async Task OnParametersSetAsync()
{
if (pickedWeek.Number > 0 && firstRender)
{
dataFromService = await _injectedService.MakeACall(pickedWeek.Id);
firstRender = false;
// MAYBE call this if it doesn't work without
StateHasChanged();
}
}
另一种方法是使用 OnAfterRender
覆盖,它提供了一个 firstRender
bool的方法签名,你可以做类似的逻辑。不过我更倾向于第一种方式,因为第二种方式允许它渲染,然后设置你的列表的值,然后导致另一个重新渲染,这对我来说似乎比需要的更多的唠叨。然而如果你的任务是长期运行的,使用这第二个版本,并建立一个加载消息,在列表为空时显示,另一个在服务调用失败时显示。"failure "有点误导你,因为它是在调用完成之前显示的。
我还发现,调用 await Task.Delay(1);
放置在服务调用之前,这一点很有用,因为它将UI线程从服务调用等待器中解脱出来,并允许你的应用程序在数据回来之前处于加载状态。