我想添加一些用例ValueChanged
and ValueExpression
,
首先,正如 enet 所说,这些属性更像是三位一体的属性,其中您拥有Foo
, FooChanged
and FooExpression
它用于双向数据绑定,例如@bind-Foo="SomeProperty"
.
创建具有可用于以下用途的属性的自定义组件@bind-
您需要提供这3个属性(仅提供Foo
and 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
and ValueChanged
,唯一的区别是@bind-
只会设置属性,但如果您添加自己的属性ValueChanged
,您可以执行任何您想要的操作(验证、更改要设置的值等)。
用例
1 - 创建一个组件来包装另一个组件@bind-
如果您的组件已经具有@bind-Foo
并且您想在其之上创建一个组件并仍然作为参数传递@bind-Foo
,您只能拥有一项财产并传递给@bind-Foo
,您需要将属性传递给Foo
, FooChanged
and/or FooExpression
.
e.g.
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 - 添加默认值
如果你想在 a 中有一个默认值自定义组件,您“可以”只将默认值传递给属性。
[Parameter]
public virtual DateTime Value { get; set; } = new DateTime(/* some default value*/);
但如果您在表单中使用此组件,则会出现一个大问题。
Why?因为你只会改变组件内部的值,但是如果传入一个属性@bind-Value
它不会被改变。
要添加此默认值并使其在双向数据绑定中工作,您需要调用ValueChanged
并传递默认值。这将使您的组件具有默认值,并且还将更改中的任何属性@bind-Value
具有默认值。
e.g.
// 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
当您有可为 null 的类型时,例如int?
,有时,当值为null
,它不知道它的类型,所以你需要通过FooExpression
所以它可以通过反射获取类型。这是一个example https://github.com/dotnet/aspnetcore/issues/12226#issuecomment-514346015你需要在哪里使用它。
如果您正在制作自定义组件并且必须使用绑定属性或更改绑定的工作方式,则将更多地使用这些属性的用例。
如果您仅使用已经制作的组件,则很少有需要使用它的情况。