Как использовать bloc и прослушивать bloc.state вручную в dart, а НЕ через канал bloc Flutter ИЛИ AngularDart?

Я следую шаблону, предложенному в блоке, для того, чтобы мой блок вызывал мои репозитории, которые обертывают мои клиентские классы api, которые выполняют вызовы RESTful для моего API. Я помещаю все это в общую библиотеку, которая используется совместно Flutter и Angular dart в соответствии с шаблоном, показанным в руководствах по блоку. Я хотел бы узнать, как отправлять те же события в мои блоки, которые используют Flutter и Angular dart из программы CLI dart, которую я также пишу, и прослушивать изменения в состоянии и получать данные, возвращаемые из API. (Я мог бы запустить программу командной строки dart для всех репозиториев напрямую, но я хотел сделать все, отправляя события в блоки.)

Почти все примеры кодирования и использования для Bloc, где блоки используются приложениями, которые я могу найти, основаны на Flutter. Есть несколько здесь и там для AngularDart (и те, которые используют преимущественно канал блока). Я вижу очень мало примеров использования Bloc вручную в другом коде Dart, таком как CLI / консольная программа или в модульном тестировании.

Я хотел бы написать простой интерфейс командной строки для выполнения вызовов API посредством отправки событий Bloc и ответа на изменения состояния из Bloc. (Я очень привык использовать ngRx и Angular для управления состоянием, и я пытаюсь найти здесь хороший шаблон для прямого кода дротика и модульного тестирования дротика для вызова моих блоков. Я довольно привык к шаблону эффектов ngRx которые делают вызовы API и пишут селекторы и слушают их на предмет изменений состояния (код RxJs). Мне было трудно перевести это на dart / bloc.

Я мог бы использовать несколько примеров кода или предложений для вызова своих блоков и прослушивания изменений состояния и получения состояния из выполняемых вызовов API. Я хотел бы сделать это ВНЕ блока (например, с помощью свойства .state) и не переопределять методы внутри блока, такие как преобразования. (Возможно, делегат - это хороший вариант, я не знаю ... кажется, что использование свойства .state было бы идеальным.)

Я рассматриваю сценарий отправки события (ItemQuery) в блок. Это событие указывает блоку выполнить вызов API, который возвращает список элементов с сервера. Блок возвращает состояние (ItemsLoading) сразу в mapeventtostate при запуске вызова. Когда вызов api завершается, блок возвращает состояние (ItemsLoaded), и это состояние содержит список, возвращенный из вызова API. (Ошибка вернет (ItemsErrorState).

Мне нужно было начать с того, как настроить код дротика, чтобы слушатель наблюдал за изменениями состояния из моего блока. После настройки слушателя код отправляет событие LoadItems, и слушатель ждет изменений состояния (ItemsLoading) и (ItemsLoaded), а затем получает список из состояния ItemsLoaded - без использования Flutter или Angular Dart - все в прямом эфире код. Подходящие примеры в сети или в stackoverlow в другом месте были бы замечательными.

Я попытался вызвать свой блок с помощью модульных тестов dart.

Мне удалось заставить этот код работать в тесте, чтобы проверить порядок получения событий (в данном случае фильтрация списка до 1 элемента). Однако на самом деле это не помогает мне получить данные из события ItemStateLoaded во время теста или отправить событие ItemQuery из программы Dart CLI, которую я пишу, и получить Item (ы), возвращенные в ItemStateLoaded.

Этот тест работает:

test('ItemBloc - Query filter for id == 1', () {
      ItemBloc ib = ItemBloc();

      expectLater(
          ib.state,
          emitsInOrder([
            new TypeMatcher<InitialItemState>(),
            new TypeMatcher<ItemStateLoading>(),
            new TypeMatcher<ItemStateLoaded>()
          ]));
      ApiDataConfig c = new ApiDataConfig()
        ..filter = 'id eq 1';
      ib.dispatch(ItemQuery());
    });

Я немного застрял и хотел бы увидеть, как использовать мои результаты API в блоке из прямого кода дротика, а не через канал блока Flutter или Angular Dart. Я хотел бы получить список элементов, который возвращается в событии ItemStateLoaded из прямого кода дротика.


person tommycox    schedule 22.07.2019    source источник


Ответы (1)


Я отвечаю на свой вопрос (который был длинным). Ответ был довольно прост, так как я только изучаю Dart and Bloc.

Мои настройки проекта для этого "приложения элемента" имеют такую ​​структуру папок:

  • item_angular - папка для углового дротика "веб-приложение элемента"
  • item_flutter - папка для флаттера "мобильное приложение элемента"
  • item_common - блоки и общий код, общий для двух

Эта структура папок выше соответствует примерам в руководстве по блоку. Я добавил еще одну папку:

  • item_cli - приложение cli, которое использует те же блоки в item_common, что и приложения angluar и flutter.

Пример кода вызова работающего блока в item_common:

_handleItemEvent(ItemState state) {
  if (state is InitialItemState) {
    print('Initial Item State');
  }
  if (state is ItemStateLoading) {
    print('Loading...');
  }
  if (state is ItemStateLoaded) {
    print('Loaded... ' + jsonEncode(state.items[0]));
  }
  if (state is ItemStateError) {
    print('Error ' + state.error);
  }
}

main() async {
  ItemBloc ib = ItemBloc();
  ib.state.listen(_handleItemEvent, onDone: ib.dispose);
  print('Listening');
  ib.dispatch(ItemQuery());
}

Этот код создает ItemBloc, подписывается на поток событий через ib.listen, отправляет событие Query, чтобы сообщить Bloc о необходимости вызова веб-API для получения элементов. Блок выдает состояние «Загрузка», затем вызывает уровень репозитория, чтобы выполнить вызов API для получения элементов, и возвращает состояние «Загружено», которое содержит полученные элементы после их успешного получения.

Результат выглядит так:

Listening..
Initial Item State
Loading...
Loaded... [{the json objects returned}]

Этот шаблон отвечает на вопрос о прямом использовании Bloc в приложении CLI с использованием прямого кода дротика (без зависимостей от Flutter или AngularDart). Блок в общей библиотеке используется совместно AngularDart и Flutter, а также приложением обслуживания dart CLI.

person tommycox    schedule 29.07.2019