Серверная проверка Blazor не обновляет пользовательский интерфейс - PullRequest
1 голос
/ 13 апреля 2020

У меня есть компонент Blazor, представляющий форму, которая должна выполнить дорогостоящую проверку перед отправкой, чтобы обеспечить уникальность точки данных на сервере. Я пытался использовать эту документацию в качестве вдохновения: https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-3.1

Кажется, что лучшая документация для этого находится на дорожной карте документации Microsoft: https://github.com/dotnet/AspNetCore.Docs/issues/17377

Мой компонент выглядит следующим образом:

<EditForm Model="@form" OnValidSubmit="@Submit">
    <InputText @bind-Value="form.DataPoint" />
    <ValidationMessage For="() => form.DataPoint" />

    <button type="submit">Go!</button>
</EditForm>

@code {
    private Form form = new Form();
    private EditContext editContext;

    protected override void OnInitialized() 
    {
        editContext = new EditContext(form);
    }

    private async Task Submit()
    {
        var isValid = editContext.Validate() && await ServerValidate(editContext);
        if (isValid) 
        { 
            // do stuff 
        }
    }

    private async Task<bool> ServerValidate(EditContext editContext)
    {
        var form = (Form)editContext.Model;
        var validationErrors = new ValidationMessageStore(editContext);
        var isDataPointCollision = await SomeService.CheckUniqueness(form.DataPoint);
        if (isDataPointCollision)
        {
            var field = new FieldIdentifier(form, nameof(Form.DataPoint));
            validationErrors.Add(field, "This data point already exists, please type a different one");
            editContext.NotifyValidationStateChanged();
            return false;
        }
        return true;
    }
}

Мой проверочный код работает правильно, обнаруживает столкновение и предотвращает отправку формы. Однако пользовательский интерфейс не обновляется, как ожидается, с компонентом <ValidationMessage [...] />. Обновление пользовательского интерфейса вообще не происходит, и сообщения проверки не отображаются. Я также пробовал этот компонент:

<ValidationSummary Model="@form" />

безрезультатно.

Нет ошибок ни на сервере, ни на стороне клиента JS.

При таком подходе я лаю не на том дереве, или я где-то пропустил соединение? Есть ли лучший способ выполнить sh то, что я хочу сделать?

Ответы [ 3 ]

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

Вы создаете (и обновляете) EditContext, который не прикреплен к форме пользовательского интерфейса.

Измените первую строку на (примечание: без модели):

 <EditForm EditContext="editContext"  OnValidSubmit="Submit">

Остальная часть вашего кода может оставаться как есть, нет необходимости в StateHasChanged () или чем-либо еще.

На первой странице документов, на которую вы ссылаетесь, выполните поиск "_editContext"

0 голосов
/ 22 апреля 2020

Хенк ответ правильный. Пара дополнений

  1. Добавить <DataAnnotationsValidator /> и <ValidationSummary /> ниже <EditForm> для проверки отдельных полей, управляемой аннотациями моделей, и сводные сообщения об ошибках формы (над формой в дополнение к каждому полю), если по желанию.
  2. После добавления сообщения в поле (validationErrors.Add(field, "This data point already exists, please type a different one");) сообщение будет сохраняться, и будущие отправления будут игнорироваться как недействительные.
  3. При этом будет запускаться только OnInvalidSubmit() точка из-за ошибки проверки выше и ее сопряжения с OnValidSubmit(). Ошибка должна быть очищена для продолжения нормальной обработки.
  4. Я нашел только грубый способ устранения ошибок, а именно с помощью метода ClearError() для повторной инициализации EditContext:
    public void ClearErrors()
    {
        _editContext = new EditContext(form);
        isSubmitButtonDisabled = false;
        showClearErrors = false;
    }

Затем я подключаю его к кнопке, которая отображается при showClearErrors=true, и отключаю кнопку «Отправить». Если есть лучший способ исправить ошибки, я весь слух.

0 голосов
/ 13 апреля 2020

Позвоните StateHasChanged после проверки:

    private async Task Submit()
    {
        var isValid = editContext.Validate() && await ServerValidate(editContext);
        if (isValid) 
        { 
            // do stuff 
        }
        StateHasChanged();
    }

Примечание: или вызовите его внутри editContext.NotifyValidationStateChanged(), если у вас есть доступ к компоненту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...