Двухстороннее связывание через несколько компонентов - PullRequest
0 голосов
/ 29 октября 2019

Я пытаюсь привязать поле модели к элементу управления, оно работает с формой, но я пытаюсь реорганизовать компоненты, чтобы можно было повторно использовать элемент управления и его атрибуты в программе.

Вот некоторые фрагменты, чтобы попытаться изобразить мою ситуацию:

Пример модели

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, повторяющийся в приложении, который связан с моделью двумя способами, независимо от слоев компонентов, через которые он прошел. Есть идеи?

1 Ответ

0 голосов
/ 29 октября 2019

Действительно сложно ответить на ваш вопрос с таким большим количеством кода, отсутствующего или неизвестного. Однако я постараюсь оказать некоторую помощь, надеясь, что она поможет вам решить ваши проблемы.

  1. Этот код:

    await 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; }
}

Надеюсь, это поможет ...

...