Блок флаттера заполняет начальное состояние данными

У меня вопрос о правильном размещении кода блока, так сказать. Так как bloc обозначает компонент бизнес-логики, я переместил бизнес-логику (например, методы обработки данных) внутрь класса. Итак, теперь есть 2 метода: один для получения и второй для сохранения данных. Затем у меня есть компонент, который внутри AddInitial должен показывать загрузку, затем пожарный блок говорит: "Эй, мне нужны данные здесь". Это правильно или это антипаттерн? Код выглядит так.

BlocBuilder<AddBloc, AddState>(
  buildWhen: (previous, current) {
    // code is ommited
  },
  builder: (context, state) {
    if (state is ExpensesLoaded || state is CategoryChanged) {
      // code is ommited
    } else if (state is ExpensesLoading) {
      return getProgressSpinner();
    } else if (state is AddInitial) {
      // is it ok? If it's antipattern please give an advise how to do it correctly
      context.bloc<AddBloc>().add(CategoryChange([category]));
      return getProgressSpinner();
    } else {
      print('Bloc Loaded. Nothing to show inside Month Expenses...');
      return Container();
    }
  }

Вопрос по поводу context.bloc<AddBloc>().add(CategoryChange([category]));. Это антипаттерн? Как это сделать?

Кстати, когда это выглядит так. В следующий раз, когда я добавлю событие CategoryChange в блок (которое даст состояние CategoryChanged), построитель сверху по какой-то причине не отреагирует ...

Спасибо!

Я использую Flutter 1.22.3, flutter_bloc: 6.1.0


person Alexander    schedule 10.11.2020    source источник


Ответы (1)


Как это сделать?

Когда вы знаете свое начальное состояние своего блока при его создании (скажем, статический список с первой записью, предварительно выбранной по умолчанию), вы можете использовать конструктор Bloc, который принимает это начальное состояние в качестве параметра.

Если вы не знаете, что такое правильное начальное состояние, потому что оно динамическое (скажем, список местоположений, загруженных из службы на основе GPS, которые пользователь должен согласиться получить нажатием кнопки, потому что это стоит денег), тогда это отлично нормально иметь пустое или неинициализированное состояние или состояние waitForUserInteraction. В конце концов, это состояние вашей программы.

Кстати, когда это выглядит так. В следующий раз, когда я добавляю событие CategoryChange в блок (которое даст состояние CategoryChanged), построитель сверху по какой-то причине не реагирует

Блок узнает, следует ли отправлять новое изменение состояния, сравнивая старое и новое состояние. Если вы хотите изменить поведение по умолчанию, вы можете убедиться, что два состояния сравниваются как равные (или нет). Самый простой способ сделать это - получить свои состояния из Equatable в пакете equatable следующим образом:

@immutable
abstract class SomeState extends Equatable {
  final String importantChange;
  final String unimportantChange;

  const SomeState(this.importantChange, this.unimportantChange);

  @override
  List<Object> get props => [importantChange]; 
}

Указание только одного поля в списке свойств означает, что при сравнении на равенство сравнивается только оно. Если importantChange равно, состояния считаются равными (и не выводятся из Блока). Два состояния с одинаковым importantChange, но разными unimportantChange считаются одинаковыми.

person nvoigt    schedule 11.11.2020
comment
Спасибо. Здесь немного другая логика. На самом деле это смесь всего, что вы написали. Я хочу показать экран с несколькими завершенными виджетами, и один виджет будет запускаться с загрузчиком (в то же время будет запущен запрос db). После того, как db ответит, соответствующий виджет должен быть обновлен - person Alexander; 17.11.2020