我正在制作一个Blazor服务器端项目,我想创建一个单击后便停用的按钮,但不使用disabled
的{{1}}属性。代码很简单:
<button>
出于奇怪的原因,第一个@functions {
LogInForm logInForm = new LogInForm();
bool IsDisabled;
SignInResult result;
protected override void OnInitialized()
{
IsDisabled = false;
}
async Task TryLogIn()
{
IsDisabled = true;
StateHasChanged();
result = await _LogInService.TryLogIn(logInForm);
Console.WriteLine("Logging status : " + (result.Succeeded ? "Sucess" : "Failure"));
IsDisabled = false;
StateHasChanged();
}
}
没有触发,但是第二个确实重新渲染了页面。通过进入Debug模式并进入StateHasChanged
方法,可以很容易地进行测试。在第二次调用时,它会在进入方法后停止在HTML代码上,但不是第一次。
为什么?
NB:我不是在寻找仅使用StateHasChanged()
或Task.Delay
的变通办法,因为它存在那些线程与UI刷新线程之间的竞争状态,并且因此这不是一个可靠的解决方案。我正在寻找Task.Run(...)
行为或解决方法的答案,方法是使用StateHasChanged()
或PropertyChanged
之类的事件并将按钮作为子组件。
编辑:经过一些测试,看来EventCallback
仅在对StateHasChanged()
进行await
操作之后才触发组件的重新渲染。可以通过在Task
行中添加注释或将result = await _LogInService.TryLogIn(logInForm);
更改为IsDisabled = ...
来轻松地对其进行测试。我现在有一些解决方法,但是我仍然想知道为什么这是一个功能。 await new Task.Run(() => { IsDisabled = ...})
是否应在执行任何操作后重新渲染?还是认为只有StateHasChanged()
个操作(因此大部分是服务器调用)才能更改UI中的某些内容?