Value 和 @bind-Value 之间的区别?

Jaz*_*zz. 2 data-binding checkbox binding 2-way-object-databinding blazor

InputCheckBox 我正在查看https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.forms.inputcheckbox的文档,我发现它公开Value绑定到所需的布尔值(Gets or sets the value of the input. This should be used with two-way binding.)。尽管如此,到处都有人在使用@bind-Value,而且我无法Value上班。

这怎么样:

<InputCheckbox @bind-Value="model.IsSelected"></InputCheckbox>
Run Code Online (Sandbox Code Playgroud)

与此不同(以及为什么这个不起作用):

<InputCheckbox Value="@model.IsSelected"></InputCheckbox>
Run Code Online (Sandbox Code Playgroud)

我还注意到,@bind-Value更新/通知模型有关更改的信息,并更新依赖于 的任何属性IsSelected,而Value不会(可能除非明确指定?)。此外,在使用 时Value,我还需要ValueExpression为标签添加 a (否则它不会呈现)。这是什么ValueExpression??在什么情况下有人会实施不同的ValueExpression

使用有Value什么好处吗?需要什么才能让它发挥作用?我在这里错过了什么吗?

MrC*_*tis 5

更多的背景信息和解释InputBase

所有InputBase继承的组件都实现三个Parameters

  1. Value是控件的“in”值 - 它是强类型的。
  2. ValueChanged是控件的“out”值:具有强类型值的回调。
  3. ValueExpressionFunc定义实际模型对象/属性的委托。它在内部用于创建一个FieldIdentifier对象,该对象用于标识 和 中的EditContext属性ValidationStore

本页演示了两种设置绑定的方法。

第一个是手动执行并将更改连接到回调方法。当您除了设置值之外还想运行其他代码时,可以使用此选项。(我正在设置时间戳)。

第二种使用 提供的“合成糖” Razor@bind-Value告诉 Razor 编译器构建一组代码,以将三个参数与Value提供的模型属性的通用名称链接起来。

@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

<InputCheckbox class="form-check"
               @bind-Value=this.model.Value />

<InputCheckbox class="form-check"
               Value=this.model.Value
               ValueChanged=this.OnValueChanged
               ValueExpression="() => this.model.Value" />

<div class="alert alert-info">
    Value: @this.model.Value
</div>

<div class="alert alert-info">
    @this.message
</div>

@code {
    private Model model = new();
    private string message = "No Message";

    private Task OnValueChanged(bool value)
    {
        this.model.Value = value;
        // You can do other stuff here if you need to
        this.message = $"Set at {DateTime.Now.ToLongTimeString()}";
        return Task.CompletedTask;
    }

    public class Model
    {
        public bool Value { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

在编译后的低级 C# 代码中,它们实际上是相同的东西。

这是完整的绑定:

private RenderFragment FirstComponent => __builder =>
{
    __builder.OpenComponent<InputCheckbox>(5);
    __builder.AddAttribute(6, "class", "form-check");
    __builder.AddAttribute(7, "Value", RuntimeHelpers.TypeCheck<Boolean>(this.model.Value));
    __builder.AddAttribute(8, "ValueChanged", RuntimeHelpers.TypeCheck<EventCallback<Boolean>>(EventCallback.Factory.Create<Boolean>(this, RuntimeHelpers.CreateInferredEventCallback(this, __value => this.model.Value = __value, this.model.Value))));
    __builder.AddAttribute(9, "ValueExpression", RuntimeHelpers.TypeCheck<global::System.Linq.Expressions.Expression<System.Func<System.Boolean>>>(() => this.model.Value));
    __builder.CloseComponent();
};
Run Code Online (Sandbox Code Playgroud)

这是手动绑定:

private RenderFragment SecondComponent => __builder =>
{
    __builder.OpenComponent<InputCheckbox>(11);
    __builder.AddAttribute(12, "class", "form-check");
    __builder.AddAttribute(13, "Value", RuntimeHelpers.TypeCheck<global::System.Boolean>(this.model.Value));
    __builder.AddAttribute(14, "ValueChanged", RuntimeHelpers.TypeCheck<EventCallback<Boolean>>(EventCallback.Factory.Create<Boolean>(this, this.OnValueChanged)));
    __builder.AddAttribute(15, "ValueExpression", RuntimeHelpers.TypeCheck<Expression<System.Func<System.Boolean>>>(() => this.model.Value));
    __builder.CloseComponent();
};
Run Code Online (Sandbox Code Playgroud)

Net7.0 @input-value:get 和 @input-value:set

Net7.0 实现了更多的语法糖,让您可以用另一种方式进行绑定。它还添加了第三个@input-value:after绑定,以提供一种方法来执行我上面显示的时间戳。

请参阅此以获取最新的绑定信息 - https://learn.microsoft.com/en-us/aspnet/core/blazor/components/data-binding