Blazor 7 中的bind:after 和bind:set 有什么区别?

Ara*_*ani 10 binding blazor .net-7.0

最近,Blazor 7 中添加了一项功能,可以更轻松地根据绑定表达式的变化来绑定和调用方法。

在 .NET 7 中,您现在可以使用新的 @bind:after 修饰符在绑定事件完成后轻松运行异步逻辑:

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

    async Task PerformSearch()
    {
        // Do something async with searchText
    }
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,PerformSearch 异步方法在检测到搜索文本的任何更改后自动运行。

还添加了另一种方法。@bind:get 和 @bind:set 修饰符始终一起使用。@bind:get 修饰符指定要绑定的值,@bind:set 修饰符指定值更改时调用的回调。

问题是:

@bind:after="PerformSearch"和 和有什么区别@bind:set="PerformSearch"PerformSearch这两个似乎都在更改后调用searchText

各自的用处在哪里?

MrC*_*tis 8

@bind:after="PerformSearch" 和 @bind:set="PerformSearch" 有什么区别?

  1. 您应该只使用@bind:after="PerformSearch"with @bind="searchText",在这种情况下,绑定将设置 的值searchText,因此您不应该尝试将其设置为PerformSearch

  2. 如果使用,则必须设置in@bind:set="PerformSearch"的值,然后使用。searchTextPerformSearch@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();
    }
}
Run Code Online (Sandbox Code Playgroud)

让我们看看 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));
Run Code Online (Sandbox Code Playgroud)

这只是调用分配给 set 的 setter 委托。

:bind=this.Value这是使用and时的代码片段@bind:after=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));
Run Code Online (Sandbox Code Playgroud)

情况有点复杂。编译器构建与此等效的内容:

Task AnonymousMethod(string __value)
{
    this.Value = __value;
    return DoSearch()
}
Run Code Online (Sandbox Code Playgroud)

关于开发环境错误的说明

根据您的开发环境,某些组合可能会出现错误。其中一些目前看来是误导性的或完全错误的。它们很快就会被修复。

引用丹·罗斯的话:大家好。VS 对此的修复刚刚错过了 17.4.4 的窗口,但应在 2 月份的下一个 VS 补丁更新中解决。我们对您的等待表示歉意,并感谢您的耐心等待!

在视觉工作室中。

这是一个正确的错误:

<InputText class="form-control" @bind-Value:get="this.searchText" @bind-Value:set="this.SetSearchText" @bind-Value:after="DoSearch" />
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)

虽然这是牛!

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.
Run Code Online (Sandbox Code Playgroud)

虽然它给出了这个错误编译并运行!

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?>' 
Run Code Online (Sandbox Code Playgroud)

还有这一行:

<input class="form-control mb-3" type="text" @bind:get="this.Value" @bind:after="ValueSetter" />
Run Code Online (Sandbox Code Playgroud)

编译但显然也是完全牛。

<input class="form-control mb-3" type="text" @bind:get="this.Value" @bind:set="ValueSetter" @bind:event="oninput" />
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述