我正在制作一个Blazor服务器端项目,我想创建一个单击后即可停用的按钮,但不使用disabled
的<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();
}
}
出于奇怪的原因,第一个StateHasChanged
不会触发,但是第二个会重新渲染页面。通过进入Debug模式并进入StateHasChanged()
方法,可以很容易地进行测试。在第二次调用时,它确实在进入方法后停止在HTML代码上,但不是第一次。
为什么这样 ?
注意:我不是在寻找仅使用Task.Delay
或Task.Run(...)
的解决方法,因为它们存在于这些线程和UI刷新线程之间的竞争状态,因此它不是可靠的解决方案。我正在通过使用诸如StateHasChanged()
或PropertyChanged
之类的事件并将按钮作为子组件来寻找有关EventCallback
行为或解决方法的答案。
编辑:经过一些测试,似乎StateHasChanged()
仅在await
上执行Task
操作后才触发组件的重新渲染。可以通过在result = await _LogInService.TryLogIn(logInForm);
行中添加注释或将IsDisabled = ...
更改为await new Task.Run(() => { IsDisabled = ...})
来轻松对其进行测试。我现在有一些解决方法,但是我仍然想知道为什么这是一个功能。 StateHasChanged()
是否应在执行任何操作后重新渲染?还是认为只有async
操作(因此大部分是服务器调用)才能更改UI中的某些内容?
参考方案
以下是描述重新渲染如何发生的执行流程:
父组件调用StateHasChanged
产生了一个新的渲染树
老树和新树之间的差异正在发生
传递给您的子组件的值被认为与其当前持有的值不同。
在子组件上调用SetParameters,以使用父级传递给它的值更新它们。
现在,在将值分配给局部变量IsDisabled之后调用StateHasChanged时,并不会真正更改组件的状态,因此没有理由调用StateHasChanged会产生重新渲染。当您调用StateHasChanged时,它只是将该组件的渲染请求排队。但是没有理由重新渲染...
或者它认为只有异步操作(因此大部分是服务器调用)才能
更改UI中的某些内容?
除了OnInitializedAsync方法外,操作的类型是否异步都无关紧要,在这种情况下,当OnInitializedAsync方法完成以再次使用新数据重新渲染UI时,将自动调用StateHasChanged方法。由异步调用检索的结果在OnInitializedAsync方法中执行。
更新:
您想要的东西可以通过多种方式完成,其中最简单的方法如下所示:
<input type="button" value="Click me now" disabled="@IsDisabled" @onclick="TryLogIn" />
@code{
bool IsDisabled;
protected override void OnInitialized()
{
IsDisabled = false;
}
async Task TryLogIn()
{
IsDisabled = true;
// Do some async work here...
// Note: Replace your async method with Task.Delay
await Task.Delay(5000);
IsDisabled = false;
}
}
这应该工作...
注意:禁用按钮控件的唯一方法是使用disabled属性
无需调用StateHasChanged方法。当编译器为您的组件创建EventCallback“委托”时,编译器插入您的源代码中的代码会自动调用它。
触发UI事件后,将自动调用StateHasChanged方法。
当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…
改造正在返回一个空的响应主体 - java我正在尝试使用Retrofit和Gson解析一些JSON。但是,我得到的响应机构是空的。当我尝试从对象中打印信息时,出现NullPointerException。我确保URL正确,并且我也确保POJO也正确。我正在使用jsonschema2pojo来帮助创建POJO类。这是我要解析的JSON{ "?xml": { "@versi…
每个文件合并后添加换行 - python我有很多类似以下内容的JSON文件:例如。1.json{"name": "one", "description": "testDescription...", "comment": ""} test.json{"name"…
Json到php,json_decode返回NULL - php我正在用PHP进行JSON解析器的一些API,用于存储有关遗产的信息。我在解析时遇到问题,因为它返回的是NULL值而不是数组或对象。简单的JSON代码可以很好地解析,但是可以这样:{"success":true,"totalCount":1,"data":[{"id":99694…
将ajax的值存储到javascript变量中 - javascript我有一个php文件,其中我从服务器获取数据。该php文件的输出是一个包含json格式数据的变量。PHP文件:<?php $dbHostName = "localhost"; $dbUserName = "venseld"; $dbUserPass = "wecuuu"; $dbName = &…