Blazor — эквивалент Vue Watch для параметра

#vue.js #blazor

#vue.js #blazor

Вопрос:

Исходя из фона VueJS для Blazor, я не могу найти эквивалент Vue watcher в Blazor.

Чтобы уточнить, в Vue можно было следить за изменениями в определенном свойстве, например:

 watch: {
   somethingId(newValue) {
      // Do something, this actually watches the somethingId for change and trigger this function
   }
}
  

Кажется, я не могу найти эквивалент Blazor, я пытался добиться этого, используя getter / setter пользовательского свойства, но это работает не во всех случаях (на самом деле это больше похоже на вычисляемые свойства в vue, а не на часы).

Есть ли способ добиться этого?

Комментарии:

1. В C # вы можете реализовать INotifyProperyChanged . learn.microsoft.com/en-us/dotnet/api/… Это то, что вам нужно?

2. Как я могу реализовать это для параметра в компоненте Blazor?

3. @ZiadAkiki вам, вероятно, это не нужно. Blazor уже замечает, когда значения полей и параметров изменяются. Что вы пытаетесь сделать? Опубликуйте фактический код Blazor . Или фактический код Vue , который показывает, что вы хотите сделать // Do something, this actually watches , но ничего не объясняет

Ответ №1:

Эта функциональность недоступна в Blazor в соответствии с командой на ASP.NET Репозиторий Github.

В итоге я реализовал контейнер состояний (аналогичную концепцию Vuex в VueJS) для хранения общих значений, которые я хочу наблюдать (вместо того, чтобы передавать их как Parameters ) и генерировать события при их изменении. Это задокументировано в ASP.NET Управление состоянием основного Блейзора.

Допустим, нам нужно наблюдать / наблюдать за изменениями somethingId , аналогично приведенному выше примеру:

  1. Создайте SomethingStateContainer класс со следующим:
 public class SomethingStateContainer
{
    public event Action<int> OnSomethingIdChanged; // Or any type, here SomethingId is an int

    private int _somethingId = 0;
    public int SomethingId {
        get => _somethingId;
        set {
            _somethingId = value;
            OnSomethingIdChanged?.Invoke(value);
        }
    }
}
  

Затем эта служба добавляется как синглтон в Program.cs (если используется Blazor WebAssembly):

 builder.Services.AddSingleton<SomethingStateContainer>();
  
  1. Каждый компонент, который хочет прослушать изменения, внесенные в эту переменную, может сделать это следующим образом:
  • Внедрить SomethingStateContainer в компонент Blazor:
 @inject SomethingStateContainer SomethingStateContainer
  
  • Добавьте прослушиватель событий (и удалите его, когда закончите):
 protected override async Task OnInitializedAsync()
{
    SomethingStateContainer.OnSomethingIdChanged  = YourCallbackFunction;
}

public void Dispose()
{
    SomethingStateContainer.OnSomethingIdChanged -= YourCallbackFunction;
}
  

Где YourCallbackFunction это функция, которую вы хотите выполнить (в данном случае она принимает в int качестве входных данных):

 private void YourCallbackFunction(int id)
{
    // Do something
}
  

Комментарии:

1. Зачем это делать? Blazor уже отслеживает изменения полей и параметров в компоненте. В Fetch примере вы видите, что Blazor замечает forecasts изменения и перерисовывает пользовательский интерфейс. INotifyPropertyChanged используется для изменений внутри модели, в WPF и WinForms. НО в React и Vue, где компоненты обычно небольшие и в любом случае не должны отслеживать глубокие изменения, это не требуется

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

3. @PanagiotisKanavos Вы правы, при привязке к параметру пользовательский интерфейс будет обновляться автоматически. Но в моем конкретном сценарии мне нужно вызвать определенное действие для выполнения (вызов API) при изменении этого параметра, вот почему мне нужно было прибегнуть к этому. Кроме того, этот конкретный параметр используется в нескольких компонентах на странице, так что это также избавляет меня от необходимости передавать его всем компонентам вручную.

4. В этом случае вы можете использовать EventCallback. Blazor ближе к тому, как работает React — изменения состояния передаются вниз, а родители уведомляются через обратные вызовы. Вы можете использовать один метод для обработки событий из нескольких компонентов. Blazor знает, что EventCallback изменит состояние, поэтому нет необходимости вызывать StateHasChanged

Ответ №2:

Используйте OnParametersSet(), это событие произойдет после инициализации.

введите описание изображения здесь

 @code{
  [Parameter] public int UserId{get;set;}
  private int _userId;

  protected overrid void OnParametersSet(){
    if(_userId!=UserId){
      _userId=UserId;
      //do something
    }
  }
}