Двухстороннее связывание данных внутри шаблона Blazor - PullRequest
0 голосов
/ 27 апреля 2020

Я хотел бы использовать двустороннюю привязку данных между компонентом внутри шаблона и его родителями. Односторонняя привязка данных работает хорошо. Но когда я изменил Контекст, переданный из RenderFragment, эта модификация не распространяется на шаблон (контейнер). Вот пример.

Это определение шаблона. У нас есть форма, и мы хотим иметь возможность указывать содержание формы в функции модели.

@typeparam TItem
@typeparam TItemDtoCU
@typeparam TDataService

<EditForm Model="@Item" OnValidSubmit="HandleValidSubmit" class="item-editor">
    <DataAnnotationsValidator />

    @FormContentTemplate(Item)

    <span class="save">
        <MatButton Type="submit" Raised="true">Save</MatButton>
        <MatButton Type="reset" Raised="true" OnClick="HandleCancelSubmit">Cancel</MatButton>
    </span>
</EditForm>

Здесь я использую этот шаблон

        <ModelEditorTemplate TItem="ClassName"
                             TItemDtoCU="OtherClassName"
                             TDataService="ServiceClassName"
                             ItemId="SelectedItem?.Id"
                             OnItemAdded="ItemAdded"
                             OnItemUpdated="ItemUpdated">

            <FormContentTemplate>
                <span>

                    <MatTextField Label="Name" @bind-Value="context.Name" @bind-Value:event="onchange" />
                    <ValidationMessage For="@(() => context.Name)" />
                </span>
            </FormContentTemplate>
        </ModelEditorTemplate>

Когда пользователь изменил поле MatTextField , оно сбрасывается на начальное значение, предоставленное шаблоном component.

У вас есть идея?

Редактировать 1: Больше информации о том, как мы извлекли данные

Да, TDataService извлекает компонент из REST Api. Вот частичный класс, связанный с шаблоном:

    public partial class ModelEditorTemplate<TItem, TItemDtoCU, TDataService> : ParentThatInheritsFromComponentBase
        where TItem : BaseEntity, new()
        where TDataService : ICrudService<TItem, TItemDtoCU>
    {
        public TItem Item = new TItem();
        [Inject]
        protected TDataService DataService { get; set; }

        protected override async Task OnParametersSetAsync()
        {
             //...
             await LoadItem();
             // ...
        }

        protected async Task LoadItem()
        {
            //...
            Item = await DataService.Get(ItemId.Value);
            // ....
        }
}

1 Ответ

1 голос
/ 28 апреля 2020

Когда поле внутри FormContentTemplate RenderFragment обновляет модель, он запускает метод шаблона OnParametersSetAsync, который снова выбирает данные с сервера, обновляет модель и затем перезаписывает изменения, выполненные пользователем.

Не было никаких проблем, поскольку форма ввода внутри шаблона просто плохо понимала, как он работает.

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

        public override async Task SetParametersAsync(ParameterView parameters)
        {
            _hasIdParameterChange = false;

            if(parameters.TryGetValue(nameof(ItemId), out int? newItemIdValue))
            {
                _hasIdParameterChange = (newItemIdValue != ItemId);
            }

            await base.SetParametersAsync(parameters);
        }
...