我在Blazor(服务器端)具有一个InputForm控件的EditForm。表单绑定到模型类,而InputText字段绑定到由本地存储支持的单个属性。
页面加载时,InputText显示空白值。我调用了一个InitAsync方法来异步地从本地存储中加载数据。可以,但是用加载的数据设置属性不会更新视图。
如果我使用单向绑定而不是InputText(具有双向绑定)将值绑定到span标记,则会发生相同的问题。
从存储异步加载数据后如何更新视图?
视图/组件类:
@inject Blazored.LocalStorage.ILocalStorageService localStorage
<EditForm Model="@model" class="pl-4 pr-3 py-1 loginform" OnValidSubmit="@HandleValidSubmit">
<span>model.OperID</span>
<InputText class="form-control mr-sm-2" style="width: 158px" placeholder="OperID" @bind-Value="@model.OperID"></InputText>
<button class="btn btn-success oi oi-account-login" @onclick="Login"></button>
</EditForm>
@code {
private Models.MainModel model = new Models.MainModel();
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await model.InitializeAsync(localStorage);
}
void Login()
{
}
private void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
}
模型类:
public class MainModel
{
Blazored.LocalStorage.ILocalStorageService? localStorage;
public MainModel()
{
}
public async Task InitializeAsync(Blazored.LocalStorage.ILocalStorageService localStorage)
{
this.localStorage = localStorage;
if (localStorage != null)
{
// the value loads correctly, but setting the property does not cause the view to update as it should.
// ConfigureAwait(false) makes no difference...
OperID = await localStorage.GetItemAsync<string?>("OperID").ConfigureAwait(false);
}
}
string? operID = "DUMMY"; // null;
public string? OperID
{
get
{
return operID;
}
set
{
operID = value;
if (localStorage != null)
{
localStorage.SetItemAsync("OperID", value);
}
}
}
}
答案 0 :(得分:0)
由于您正在使用服务器端Blazor,并且可能已启用了预渲染设置,因此您不能也不应使用OnIntialized或OnInitializedAsync方法。相反,您应该使用OnAfterRenderAsync方法,该方法是使用JSInterop的适当位置。并且您应该将代码包含在if语句中,以检查这是否是第一个渲染,如下所示:
protected override async Task OnAfterRenderAsync(bool firstRender)
{ if( firstRender)
{
await model.InitializeAsync(localStorage);
// And of course the StateHasChanged method should be called here to refresh the page.
StateHasChanged();
}
}
这样,您的模型仅初始化一次,而不是在每次执行OnAfterRenderAsync时(每次需要重新呈现页面组件时)都进行初始化。
注意:如果要重新渲染,则根本不会调用OnAfterRenderAsync方法。
_Host.cshtml中的以下代码片段可以告诉您是否正在使用预渲染:
<app>
<component type="typeof(App)" render-mode="ServerPrerendered" />
</app>
从设置中可以看到,您的应用已在服务器上预呈现。 Blazored.LocalStorage是否支持数据保护(如果不支持)。使用Blazor团队创建的库。
答案 1 :(得分:0)
这是我为了使其工作而更改的代码:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender) // prevent infinite loop
{
await model.InitializeAsync(localStorage); // load data
StateHasChanged(); // update view
}
}