Передача отключенного атрибута элементу HTML в дочернем компоненте не работает - PullRequest
1 голос
/ 07 февраля 2020

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

<EditForm Model="Model" OnValidSubmit="SubmitSearch">
   <div class="panel-body">
      <ChildComponent IsSubmitting="@IsSubmitting"/>
   </div>
</EditForm>

Мой дочерний компонент - это просто последовательность входов с кнопкой отправки

<div>

   // inputs etc.

   <span class="pull-left">
      <button class="btn btn-success" type="submit" disabled="@IsSubmitting">
          Submit Search
      </button>
   </span>

</div>

@code {
   [Parameter]
   public bool IsSubmitting { get; set; }
}

и мой метод отправки устанавливает IsSubmitting примерно так:

public async void SubmitSearch()
{
   IsSubmitting = true;

   var result = await Service.GetStuff();

   // do stuff with result

   IsSubmitting = false;
}

Я заметил, что кнопка никогда не отключается. Я пропускаю какой-то хук жизненного цикла для запуска повторного рендеринга при обновлении параметра?

Любая помощь приветствуется.

Ответы [ 4 ]

2 голосов
/ 07 февраля 2020

Я нашел решение в последнем ответе здесь: Как отключить / скрыть кнопку, как только она нажата в Blazor?

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

Как сказал @HenkHolterman в этом ответе, GUI не обновляется, если только вызовы методов не являются чисто асинхронными c.

Поэтому я создал асинхронный диспетчер задач c следующим образом:

    async Task DispatchSubmit()
    {
        IsSubmitting = true;

        await Task.Delay(1);  // allow the GUI to catch up
        await SubmitSearch();

        IsSubmitting = false;
    }

, который все исправил!

1 голос
/ 08 февраля 2020

Единственная проблема с вашим кодом заключается в том, что вы используете void вместо Task в методе SubmitSearch, который должен выглядеть следующим образом:

public async Task SubmitSearch()
    {
        IsSubmitting = true;

        // await Task.Delay(3000);
       // var result = await Service.GetStuff();

        // do stuff with result

        IsSubmitting = false;
    }

Приведенный выше код прекрасно работает и выполняет свою работу ...

1 голос
/ 07 февраля 2020

Вот пример кода, который отключает кнопку отправки, если модель недействительна.

using System.ComponentModel.DataAnnotations

<h1>My articles</h1>

<p>Leave me a comment</p>

<EditForm EditContext="@EditContext">
      <DataAnnotationsValidator />

<div class="form-group">
    <label for="name">Name: </label>
    <InputText Id="name" Class="form-control" @bind-Value="@Model.Name"> 
</InputText>
         <ValidationMessage For="@(() => Model.Name)" /> 

</div>
<div class="form-group">
    <label for="body">Text: </label>
    <InputTextArea Id="body" Class="form-control" @bind-Value="@Model.Text"> 
</InputTextArea>
    <ValidationMessage For="@(() => Model.Text)" />
</div>

</EditForm>
<p>
   <button>Action 1</button>
   <button>Action 2</button>
    <button disabled="@Disabled" @onclick="Save">Save</button>
</p>

@code
{
  private EditContext EditContext;
  private Comment Model = new Comment();

  protected string Disabled { get; set; } = "disabled";


private async Task Save ()
{
    await Task.Delay(3000);
    Console.WriteLine("Saving...");
    Console.WriteLine(Model.Name);
    Console.WriteLine(Model.Text);
}

protected override void OnInitialized()
{
    EditContext = new EditContext(Model);
    EditContext.OnFieldChanged += EditContext_OnFieldChanged;

    base.OnInitialized();
}

private void EditContext_OnFieldChanged(object sender, FieldChangedEventArgs 
   e)
{
    Console.WriteLine(e.FieldIdentifier.FieldName);

    SetSaveDisabledStatus(e);

}

private void SetSaveDisabledStatus(FieldChangedEventArgs e)
{
    if (EditContext.Validate())
    {
        Disabled = null;
    }
    else
    {
       Disabled = "disabled";
    }
}

public class Comment
{
    [Required]
    [MaxLength(10)]
    public string Name { get; set; }

    [Required]
    public string Text { get; set; }
} 

}

1 голос
/ 07 февраля 2020

Вы просто не можете этого сделать:

public async void SubmitSearch() // async method MUST return a Task
{
   IsSubmitting = true;

   var result = await Service.GetStuff();

   // do stuff with result

   IsSubmitting = false;

    // The component is refreshed after the method call
}

Но это должно сработать

public void SubmitSearch()
{
   IsSubmitting = true;

   Service.GetStuff()
       .ContinueWith(t => 
       {
          IsSubmitting = false;
          InvokeAsync(StateHasChanged());

          if (t.Exception != null)
          {
               throw t.Exception;
          }

          var result = t.Result;
          // do stuff with result
       });

}
...