通过多个组件进行双向绑定
Posted
技术标签:
【中文标题】通过多个组件进行双向绑定【英文标题】:Two-way binding through multiple components 【发布时间】:2020-02-24 21:31:36 【问题描述】:我正在尝试将模型字段绑定到控件,我让它在表单上工作,但我正在尝试重构组件,以便我可以在整个程序中重用控件及其属性。
这里有一些 sn-ps 试图描述我的情况:
示例模型
public class MyModel
public DateTime DateOpened get; set;
在 MyModelFormBase.cs 中使用
public class MyModelFormBase : ComponentBase
protected MyModal data = new MyModel();
用于 MyModelForm.razor
<MyForm Model="@data" AddFunction="@InsertMyModel" DataDismiss="MyModelForm">
<MyDateInput InputId="dateOpened" InputName="Date Opened" @bind-InputValue="@data.DateOpened" />
</MyForm>
MyForm.razor,使用 blazorstrap
<BSForm Model="@Model" OnValidSubmit="@AddFunction"
@ChildContent
<BSButton Color="Color.Primary"
ButtonType="ButtonType.Submit"
data-dismiss="@DataDismiss">
Submit</BSButton>
</BSForm>
@code
[Parameter]
public Object Model get; set;
[Parameter]
public RenderFragment ChildContent get; set;
[Parameter]
public EventCallback AddFunction get; set;
[Parameter]
public string DataDismiss get; set;
MyDateInput.razor,使用 blazorstrap
<BSFormGroup>
<BSLabel For="@InputId">@InputName</BSLabel>
<BSInput InputType="InputType.Date" Id="@InputId"
@bind-Value="@InputValue"
ValidateOnChange="true"
@onchange="UpdateData"
/>
<BSFormFeedback For="@(() => InputValue)"/>
</BSFormGroup>
@code
[Parameter]
public DateTime InputValue get; set;
[Parameter]
public EventCallback<DateTime> InputValueChanged get; set;
[Parameter]
public string InputId get; set;
[Parameter]
public string InputName get; set;
private async Task UpdateData()
await InputValueChanged.InvokeAsync(InputValue);
我的服务提供的默认数据正确显示在控件中,因此它正确地向下绑定,但不会将任何更改传播回模型。 :(
目标是能够保留一个MyDateInput
组件,该组件在整个应用程序中重复,该组件以两种方式与模型绑定,而不管它通过的组件层。
有任何想法吗?
【问题讨论】:
Read the doc 【参考方案1】:在有这么多代码缺失或未知的情况下回答您的问题真的很令人生畏。不过,我会尽力提供一些帮助,希望能帮助您解决问题。
这段代码:
等待 InputValueChanged.InvokeAsync(InputValue);
我猜是一个回调来更新绑定属性 MyModel.DateOpened 的值,对吧?如果不是,它应该这样做。在任何情况下,该属性都应该使用 PropertyAttribute 属性进行注释...
这可能是双向数据绑定不起作用的原因。
请注意,您的 MyDateInput 组件可能还需要接收 ValueExpression 值。我不能肯定地说,因为并非所有代码都可用,所以请作为警告:
[Parameter] public Expression<Func<string>> ValueExpression get; set;
我会在答案的最后放一个小样本来说明这一点。
你确定这有效吗?编译器应该在狂吠:
@bind-Value="@InputValue" ValidateOnChange="true" @onchange="UpdateData"
告诉你你正在使用两个 onchange 事件。通常应该是这样的
value="@InputValue" ValidateOnChange="true" @onchange="UpdateData",但我无法确定,因为我看不到 BSInput 是如何实现的...
-
注意:BSForm 在@ChildContent 之前缺少一个结束标记
示例代码:
RazorInputTextTest.razo
-----------------------
@page "/RazorInputTextTest"
<span>Name of the category: @category.Name</span>
<EditForm Model="@category">
<RazorInputText Value="@category.Name" ValueChanged="@OnValueChanged" ValueExpression="@(() => category.Name)" />
</EditForm>
@code
private Category category get; set; = new Category ID = "1", Name = "Beverages" ;
private void OnValueChanged(string name)
category.Name = name;
RazorInputText.razor
--------------------
<div class="form-group">
<InputText class="form-control" @bind-Value="@Value"></InputText>
</div>
@code
private string _value get; set;
[Parameter]
public string Value
get return _value;
set
if (_value != value)
_value = value;
if (ValueChanged.HasDelegate)
ValueChanged.InvokeAsync(value);
[Parameter] public EventCallback<string> ValueChanged get; set;
[Parameter] public Expression<Func<string>> ValueExpression get; set;
希望这会有所帮助...
【讨论】:
以上是关于通过多个组件进行双向绑定的主要内容,如果未能解决你的问题,请参考以下文章