通过多个组件进行双向绑定

时间:2019-10-29 15:46:11

标签: c# data-binding .net-core blazor blazor-server-side

我试图将模型字段绑定到控件,使它适用于表单,但是我试图重构组件,以便可以在整个程序中重用控件及其属性。

以下是一些片段来描述我的情况:

样本模型

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组件,该组件与模型绑定了2种方式,而与传递的组件层无关。 有任何想法吗?

1 个答案:

答案 0 :(得分:0)

回答这么多缺少或未知的代码真的很艰巨。但是,我会尽力提供一些帮助,希望它可以帮助您解决疾病。

  1. 此代码:

    等待InputValueChanged.InvokeAsync(InputValue);

我想是一个回调,用于更新绑定属性MyModel.DateOpened的值,对吗?如果没有,应该这样做。无论如何,该属性都应使用PropertyAttribute属性进行注释。

可能是双向数据绑定无法正常工作的原因。

请注意,您的MyDateInput组件可能还需要接收ValueExpression值。我不能肯定地说,因为并非所有代码都可用,因此请提起警告:

[Parameter] public Expression<Func<string>> ValueExpression { get; set; }

我将在答案的末尾提供一个小样本来阐明这一点。

  1. 您确定这有效吗?编译器应该吠叫:

    @ bind-Value =“ @ InputValue” ValidateOnChange =“ true” @ onchange =“ UpdateData”

    告诉您您正在使用两个onchange事件。通常应该是

    value =“ @ InputValue” ValidateOnChange =“ true” @ onchange =“ UpdateData”,但我不确定,因为我看不到BSInput的实现方式...

    1. 注意: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; }
}

希望这对您有帮助...