Blazor - подписка на изменение значения свойства - PullRequest
1 голос
/ 14 июля 2020

При работе с компонентами в Blazor мне часто требуется, чтобы дочерний компонент реагировал на изменение значения параметра и делал что-то соответственно.

В простом примере у меня есть параметр UserId, связанный между родительским и дочерние компоненты. Идея состоит в том, что, когда родительский элемент изменяет значение UserId, установщик свойств дочернего элемента вызывает метод, который считывает необходимые данные. Вот пример кода для иллюстрации.

MyParent:

<ChildComponent UserId="@UserId" />

<a onclick="@ChangeUser">Load User</a>

@code
{
   public int UserId = 0;
   
   void ChangeUser()
   {
      UserId = 1;
   }
}

ChildComponent:

@if(userDetails != null)
{
   <div>First Name: @userDetails.FirstName</div>
   <div>Surname: @userDetails.Surname</div>
}


@code
{
   private int _userId;
   
   [Parameter] public int UserId
   {
      get => _userId;
      set
      {
         _userId = value;
         LoadUserDetails();
      }
   }
   UserDetails userDetails;
   
   async Task LoadUserDetails()
   {
      userDetails = [read from server here];
      StateHasChanged();
   }
}

Теперь, пока это работает, что мне не очень нравится, так это то, что средство задания свойств в ChildComponent является синхронным, но вызывает асинхронный код (LoadUserDetails).

Каков самый чистый способ обновления UserId в родительском элементе и чтобы ребенок осознал это и вызвал в ответ метод asyn c без блокировки каких-либо потоков?

1 Ответ

1 голос
/ 14 июля 2020
@code
{
   private int _userId;
   private bool _userIdChanged;
   
   [Parameter] public int UserId
   {
      get => _userId;
      set
      {
         _userIdChanged = value != _userId;
         _userId = value;
      }
   }
   UserDetails userDetails;
   
   async Task LoadUserDetails()
   {
      userDetails = [read from server here];
      StateHasChanged();
   }

    protected override async Task OnParametersSetAsync()
    {
         await base.OnParametersSetAsync().ConfigureAwait(false);
         if (_userIdChanged)
         {
             await LoadUserDetails().ConfigureAwait(false);
         }
    }
}
...