簡體   English   中英

綁定屬性不會在更改時更新

[英]Bound property not updating upon change

在我的 Blazor 應用程序中,我在視圖中有以下輸入字段:

<input bind="@amount.Display" type="text" />

這綁定到使用以下訪問器定義的屬性:

get
{
    return _display;
}
set
{
    var parsed = Decimal.Parse(value);
    _display = parsed.ToString("F2");
}

真正的訪問器邏輯比這更復雜,但我在上面盡可能地簡化了它,同時仍然保留了讓我感到困惑的行為。

基本上,當用戶輸入“2”,然后標簽或點擊輸入字段時,我希望它自動轉換為“2.00”。 奇怪的是,這種轉換似乎只有在用戶輸入的字符串表示的數字與已經存在的數字不同時才會發生。 例如,如果輸入字段當前的值為“1.00”,而我輸入“2”,則正確地以“2.00”結尾。 但是,如果輸入字段的值為“2.00”而我輸入“2”,則它只是保持“2”。 就好像在后一種情況下沒有調用 set 訪問器,我無法想象為什么。

如果你想強制 UI 重新渲染,在 Blazor 0.6 中我建議你使用StateHasChanged()

get
{
    return _display;
}
set
{
    var parsed = Decimal.Parse(value);
    _display = parsed.ToString("F2");
    StateHasChanged();
}

Blazor 不重新渲染的真正原因是:它試圖保存重建 HTML。 由於 Blazor 知道您將屬性綁定到input因此相信在設置屬性后無需觸發重新渲染。

更新工作:

  1. 用戶輸入文本“5”並按 Tab
  2. 生成了 HTML onchange事件
  3. Blazor 捕獲onchange even 並調用amount.Display = "5";
  4. 完畢。

主要問題是,如果 Blazor 認為文本框的值沒有改變,它就不會更新文本框。 您的示例的部分問題是值(您的財產)的內部表示有時與您在文本框中看到的內容不一致( 22.00 )。 但是就 Blazor 而言,如果屬性值沒有改變,它就不會將綁定傳播回文本框。

我玩弄了您的代碼的許多變體(使用valueonchange手動“綁定”)但最終如果您的代碼完成更新 value 屬性並且該值與以前相同,則不會發生任何事情.

我能想到的唯一解決方法是使用 async 引入一個非常丑陋的 hack。 執行此操作時,事件循環在await之后完成(blazor 將接受新值2 ),並且 blazor 將在恢復await調用時再次檢查是否有任何更改,因為此時它是新一輪的事件循環。 由於新值現在將是2.00而不是2它會刷新文本框。

@functions {
    private string value;

    private string Value
    {
        get => value;
        set => SetValue(value);
    }

    private async void SetValue(string value)
    {
        this.value = value;
        await Task.Delay(1);
        this.value = decimal.Parse(value).ToString("F2");
        StateHasChanged();
    }
}

希望比我更了解 Blazor 的人可以提供一些不那么殘酷的東西。 但它確實有效。 (順便說一句, Task.Delay(0)不起作用,這可能是由於一些優化,其中的任務已經完成,因此不會將承諾讓事件循環的了。)

筆記:
一旦 Blazor 格式字符串(即format-value="yyyy-MM-dd" )接受數字,您可能可以通過將值存儲為十進制並直接在 razor 標記中使用格式字符串來簡化此操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM