我想为ValueChanged 和ValueExpression 添加一些用例,
首先,正如 enet 所说,这些属性更像是三个属性,您有 Foo、FooChanged 和 FooExpression,它用于双向数据绑定,例如@bind-Foo="SomeProperty".
要创建具有可与@bind- 一起使用的属性的自定义组件,您需要提供这三个属性(仅提供Foo 和FooChanged 也可以)作为[Parameter] 并调用FooChanged 当自定义组件中的属性发生变化。
例如来自网络
[Parameter]
public TValue Foo
{
get => text
set
{
if (text != value) {
text = value;
if (FooChanged.HasDelegate)
{
FooChanged.InvokeAsync(value);
}
}
}
}
[Parameter]
public EventCallback<TValue> FooChanged { get; set; }
[Parameter]
public Expression<Func<TValue>> FooExpression { get; set; }
添加@bind-Foo 与传递Value 和ValueChanged 相同,唯一的区别是@bind- 只会设置属性,但如果添加自己的ValueChanged,则可以做任何事情您想要(验证、更改要设置的值等)。
用例
1 - 创建一个用@bind- 包装另一个组件的组件
如果您有一个组件已经有@bind-Foo,并且您想在此基础上创建一个组件并仍然作为参数传递@bind-Foo,您可以只有一个属性并传递给@bind-Foo,您需要将属性传递给Foo、FooChanged 和/或FooExpression。
例如
CustomInputWrapper.razor
<div>
<p>My custom input wrapper</p>
@* If you pass @bind-Value it won't work*@
@* You need to pass the properties that are used in the bind*@
<InputText Text="@Value" TextChanged="@ValueChanged" TextExpression="@ValueExpression" />
</div>
@code {
[Parameter]
public virtual string Value { get; set; }
[Parameter]
public EventCallback<string > ValueChanged { get; set; }
[Parameter]
public Expression<Func<string >> ValueExpression { get; set; }
}
如果您正在制作大量自定义组件或不想直接使用某些第三方组件,这种包装另一个组件的情况会发生很多。
我的项目示例:在我的项目中,我使用的是 MatBlazor 和 Telerik,但并不是两个库中的所有组件都是完全稳定的,所以我为所有组件创建了一个包装器,有一天,当其中一个库是完全稳定的,我将改为只使用一个库。这样做可以让我拥有我的自定义组件,如果我想更改一个,我只需在我的自定义组件中更改一件事并更改整个应用程序。
2 - 添加默认值
如果您想在 自定义组件 中使用默认值,您“可以”将默认值传递给属性。
[Parameter]
public virtual DateTime Value { get; set; } = new DateTime(/* some default value*/);
但是如果你在一个表单中使用这个组件,就会有很大的问题。
为什么?因为您只会更改组件内部的值,但如果在 @bind-Value 中传递了属性,则不会更改。
要添加此默认值并使其在双向数据绑定中起作用,您需要调用ValueChanged 并传递默认值。这将使您的组件具有默认值,并且还将更改 @bind-Value 中的任何属性以具有默认值。
例如
// Lifecycle after all parameters are set
protected override void OnParametersSet()
{
// Check if the ValueChanged is set
if (ValueChanged.HasDelegate)
{
ValueChanged.InvokeAsync(DateTime.Now);
}
}
3 - 你真正需要的用例FooExpression
当你有一个可以为空的类型时,例如int?,有时,当值为null时,它无法知道它的类型,所以你需要传递FooExpression,这样它才能通过反射得到类型。这是您需要使用的example。
如果您正在制作自定义组件并且必须使用绑定属性或更改绑定的工作方式,这些属性的用例将被更多地使用。
如果您只使用已经制作的组件,那么您将不得不使用它的情况很少见。