簡體   English   中英

Blazor 7 中的 bind:after 和 bind:set 有什么區別?

[英]What is the difference between bind:after and bind:set in Blazor 7?

最近在Blazor 7中,增加了一個功能,可以更方便地根據綁定表達式的變化來綁定和調用方法。

在 .NET 7 中,您現在可以使用新的 @bind:after 修飾符在綁定事件完成后輕松運行異步邏輯:

    <input @bind="searchText" @bind:after="PerformSearch" />
@code {
    string searchText = "";

    async Task PerformSearch()
    {
        // Do something async with searchText
    }
}

在此示例中,PerformSearch 異步方法在檢測到對搜索文本的任何更改后自動運行。

還添加了另一種方法。 @bind:get 和@bind:set 修飾符總是一起使用。 @bind:get 修飾符指定要綁定的值,@bind:set 修飾符指定值更改時調用的回調。

問題是:

@bind:after="PerformSearch"@bind:set="PerformSearch"有什么區別? searchText更改后,這兩個似乎都調用了PerformSearch

每個的用途在哪里?

為什么是@bind:get+@bind:set而不僅僅是@bind+@bind:set

  • 因為如果你經常看到<input @bind="@val" @bind:set="@MyMethod" /> ,它會造成混淆:

  • 看起來好像@bind:set是使它成為雙向綁定的原因,並且您可以通過刪除它使其成為單向綁定。 而實際上那是錯誤的(您仍然有雙向綁定,只是現在行為不同)。

  • 看起來它等同於編寫<input value="@val" @bind:set="@MyMethod /> ,它幾乎是,但不完全是因為格式化邏輯會有所不同。最好不要創建歧義,並有一個正確的解決方案。

  • 我們可以通過編譯器規則避免上述問題, @bind:get@bind:set必須始終成對使用 - 你不能只使用其中一個而不使用另一個(也不能使用@bind )。 所以不會出現任何奇怪的情況。

您不能使用@bind:set來實現(實際上) @bind:after ,因此我們不需要@bind:after嗎?

  • 理論上是的。 您可以將@bind:set為寫入您的字段然后運行您的異步邏輯的方法。 然而,這對於新手來說遠沒有那么明顯,並且在常見情況下也不太方便。 它會引發錯誤:如果您在設置字段之前執行異步操作,UI 將暫時恢復並且通常表現不佳。 因此,為了方便和指導正確使用,@bind:after 很有價值。 我們可以將@bind:get/@bind:set視為更高級的案例,主要針對實現可綁定組件的人員,因為它為他們提供了一個真正干凈和安全的解決方案,並且這些開發人員足夠先進,明白他們不應該這樣做在調用ValueChanged之前異步工作。

你能同時使用這三個嗎,例如<input @bind:get="@value" @bind:set="@MyMethod" @bind:after="@DoStuff" />

  • 當然,為什么不呢? 我認為生成的邏輯應該在調用 DoStuff 之前等待 MyMethod,因為“之后”感覺它意味着“在調用 set 所涉及的所有工作之后”。 這是一個邊緣案例,但我想不出這會導致任何問題,也不會大幅增加實施成本。

@bind:event 和@bind:format等其他@bind修飾符是否適用於此?

  • 是的,這就是為什么它比手動value/onchange對有很大改進的部分原因。

你可以參考這個鏈接得到更多的想法https://github.com/do.net/as.netcore/issues/39837

@bind:after="PerformSearch" 和@bind:set="PerformSearch" 有什么區別?

  1. 您應該只將@bind:after="PerformSearch"@bind="searchText" " 一起使用,在這種情況下,綁定將設置searchText的值,因此您也不應該嘗試在PerformSearch中設置它。

  2. 如果您使用@bind:set="PerformSearch"那么您必須在PerformSearch中設置searchText的值,並使用@bind:get="searchText"

每個的用途在哪里?

我認為 MS Docs 文章提供了很好的指導。 這完全取決於您對組件的知識水平。

理解兩點很重要:

  1. 這是 Razor 語法,而不是 C#。
  2. 它只是語法糖:高級功能,簡寫 Razor 指令來封裝現有功能。

另請注意:

這是我的這個答案的演示頁面。

@page "/"

<PageTitle>Index</PageTitle>

<input class="form-control mb-3" type="text" @bind:get="this.Value" @bind:set="ValueSetter" @bind:event="oninput" />
<input class="form-control mb-3" type="text" @bind:get="this.Value" @bind:after="ValueSetter" />
<input class="form-control mb-3" type="text" @bind="this.Value" @bind:after="DoSearch" @bind:event="oninput"/>

<div class="alert alert-info m-2 p-2">
    @Value
</div>

<div class="alert alert-primary m-2 p-2">
    @message
</div>

@code {
    private string? Value; 
    private string message = "Not Set";

    private async Task DoSearch()
    {
        await Task.Delay(1000);
        message= $"Set at {DateTime.Now.ToLongTimeString()}";
    }

    private void ValueSetter(string __value)
        => this.Value = __value;

    private Task SearchSetter(string __value)
    {
        this.searchText = __value;
        return DoSearch();
    }
}

讓我們看看 Razor 編譯器構建的實際 C# 代碼。

這是僅使用bind:set=this.ValueSetter時的代碼片段:

__builder.AddAttribute(8, "oninput", EventCallback.Factory.CreateBinder(
    this, 
    CompilerServices.RuntimeHelpers.CreateInferredBindSetter(
        callback: this.ValueSetter, 
        value: this.Value
        ),
    this.Value));

這只是調用分配給 set 的 setter 委托。

這是使用:bind=this.Value@bind:after=DoSearch DoSearch 時的代碼片段:

__builder.AddAttribute(14, "oninput", EventCallback.Factory.CreateBinder(
    this, CompilerServices.RuntimeHelpers.CreateInferredBindSetter(
        callback: __value => { 
            this.Value = __value; 
            return RuntimeHelpers.InvokeAsynchronousDelegate(callback: DoSearch); 
        }, 
        value: this.Value), 
        this.Value));

這有點復雜。 編譯器構建等效於此:

Task AnonymousMethod(string __value)
{
    this.Value = __value;
    return DoSearch()
}

關於開發環境錯誤的說明

根據您的開發環境,您會遇到某些組合的錯誤。 目前,其中一些似乎具有誤導性或完全錯誤。 它們將很快得到修復。

引用 Dan Roth 的話:大家好。 VS 對此的修復只是錯過了 17.4.4 的 window,但應該在 2 月份的下一個 VS 補丁更新中解決。 對於讓您久等了,我們深表歉意,感謝您的耐心等待!

在視覺工作室中。

這是一個正確的錯誤:

<InputText class="form-control" @bind-Value:get="this.searchText" @bind-Value:set="this.SetSearchText" @bind-Value:after="DoSearch" />
Severity    Code    Description Project File    Line    Suppression State
Error (active)  RZ10019 Attribute 'bind-Value:after' can not be used with 'bind-Value:set'. Invoke the code in 'bind-Value:after' inside 'bind-Value:set' instead.

雖然這是牛!

<input class="form-control mb-3" type="text" @bind:get="this.Value" @bind:set="ValueSetter" @bind:event="oninput" />

雖然它給出了這個錯誤編譯並運行!

Severity    Code    Description Project File    Line    Suppression State
Error (active)  CS1503  Argument 3: cannot convert from 'Microsoft.AspNetCore.Components.EventCallback<string>' to 'System.Action<string?>' 

這行:

<input class="form-control mb-3" type="text" @bind:get="this.Value" @bind:after="ValueSetter" />

編不過顯然也是十足的牛逼。

__builder.AddMarkupContent(9, "\r\n\r\n<input class=\"form-control mb-3\" type=\"text\" @bind:get=\"this.Value\" @bind:after=\"ValueSetter\">\r\n\r\n");

在此處輸入圖像描述

暫無
暫無

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

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