[英]Unexpected UI binding behavior in Blazor WASM
我在 Blazor WASM 和 Blazor 服務器之間的 UI 綁定行為中遇到了意外(且莫名其妙)的差異。 鑒於以下 razor 組件,“發送”按鈕在請求期間被正確禁用,在 Blazor 服務器和 Blazor WASM 中:
<MudButton Disabled="isProcessing" OnClick="Submit">Send</MudButton>
@code {
private bool isProcessing;
private async Task Submit()
{
isProcessing = true;
var contacts = await Mediator.Send(getContacts);
isProcessing = false;
}
}
在向提交方法添加第二個等待調用( IsValidAsync()
)后,該按鈕現在在 Blazor WASM 中的請求期間保持啟用狀態,我認為這是錯誤的。 在 Blazor 服務器中,它仍然按預期被禁用:
private async Task Submit()
{
if (await validator.IsValidAsync())
{
isProcessing = true;
var contacts = await Mediator.Send(getContacts);
isProcessing = false;
}
}
為什么這種綁定在 Blazor WASM 中不起作用有明確的原因嗎? 或者這是 Blazor 中的一個明顯錯誤?
規則是您可以免費獲得 2 個隱含的 StatehasChanged() 調用,1 個在事件處理程序之前和 1 個之后。
因此,您在第一次等待中獲得了“免費更新”,但是當您的代碼中有更多步驟(需要輸出)時,您需要幫助:
private async Task Submit()
{
if (await validator.IsValidAsync()) // consumes the first StateHasChanged
{
isProcessing = true;
StateHasChanged(); // request an update
var contacts = await Mediator.Send(getContacts); // update UI in background
isProcessing = false;
}
// one implied StateHasChanged for free again
}
這種模式應該用在 Server 和 Wasm 上。 原始代碼在服務器上為您工作的原因尚不清楚。 這可能是來自 IsValidAsync() 的僥幸,具有非異步代碼路徑。
我很驚訝它的行為不同,但 Server 和 WASM 之間存在顯着差異,這可以解釋發生了什么。 我對 MudBlazor 並不完全熟悉,所以我不確定 MudBlazor 內部是如何工作的。
不同之處在於瀏覽器對於所有操作只有一個線程。 服務器盡可能多的可用在服務器實例上,這幾乎在所有情況下都不止一個。
嘗試:
private async Task Submit()
{
isProcessing = true;
if (await validator.IsValidAsync())
{
var contacts = await Mediator.Send(getContacts);
}
isProcessing = false;
}
或者
private async Task Submit()
{
if (await validator.IsValidAsync())
{
isProcessing = true;
await InvokeAsync(StateHasChanged);
var contacts = await Mediator.Send(getContacts);
isProcessing = false;
}
}
事件處理程序基本上是這樣做的:
var task = Submit();
StateHasChanged();
if (!task.IsCompleted || !task.IsCanceled)
{
await task;
StateHasChanged();
}
您可以在ComponentBase
中看到這種模式。 它說如果任務成功,那么我們更新 UI,等待它完成,然后再次更新 UI。 如果它沒有產生,那么我們會在它完成后更新 UI。 我的服務器代碼和 WASM 代碼的行為相同 - 確定您的代碼有何不同。
您的代碼在if (await validator.IsValidAsync())
中產生,因此在設置isProcessing
之前調用第一個StateHasChanged
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.