Каким образом logi c в BLo C должен запускать одноразовое оповещение пользовательского интерфейса, такое как диалог или закусочная? - PullRequest
0 голосов
/ 30 января 2020

При использовании шаблона BLo C для изоляции бизнес-логики c от представления (без библиотеки blo c ), как мы можем инициировать одноразовый вызов пользовательского интерфейса (например, показ Снэк-бар или диалоговое окно с предупреждением), когда некоторые асинхронные логики c завершились в BLo C? Например, в случае сбоя сетевого запроса мы хотим показать диалоговое окно, информирующее пользователя о том, что некоторые данные не могут быть извлечены.

Изученные параметры:

  1. Используйте StreamBuilder в методе сборки виджета для прослушивания события из блока c и отображения диалога в методе сборки StreamBuilder. Проблема с этим подходом заключается в том, что StreamBuilder build метод на самом деле не будет строить здесь что-нибудь. Мы бы просто попросили Флаттера показать диалог. Мы могли бы вернуть какой-нибудь невидимый «фальшивый» виджет только для того, чтобы Флаттер был счастлив, но это действительно забавно.

  2. Сделать виджет с состоянием. В initState подпишитесь на поток ошибок от BLo C и покажите диалог в слушателе. Здесь мы поддерживаем разъединение логики / представления, но, насколько я могу судить, эта опция даже жизнеспособно, потому что у нас нет BuildContext, необходимого для отображения диалога.

  3. Когда виджет вызывает некоторые логики c на BLo C, которые могут привести к изменению, которое должно вызвать диалог, передать обратный вызов, который показывает диалог. Из перечисленных здесь опций я предпочитаю этот. Logi c и обзор по-прежнему довольно разные, но это выглядит немного странно. Поток данных в шаблоне BLo C обычно представляет собой просто «виджет -> BLo C через приемники или функции» и «BLo C -> виджет через потоки». Это нарушение этого паттерна, когда виджет просит BLo C вызвать обратный вызов (передавая данные обратно) после выполнения некоторого logi c.

I ' мы избегали использовать библиотеку blo c (для простоты, среди прочих причин). Тем не менее, он предлагает решение этой проблемы в виде BlocListener. Есть ли простой способ решить эту проблему при сохранении основных принципов BLo C?

Ответы [ 2 ]

1 голос
/ 30 января 2020

Я просто работал над этой проблемой. Это было мое решение - оно попадает в категорию # 2:

class CurrencyStreamListener extends StatefulWidget {
  final Stream<CurrencyNotification> notificationStream;
  final Widget child;
  CurrencyStreamListener({this.notificationStream, this.child});

  @override
  _CurrencyStreamListenerState createState() => _CurrencyStreamListenerState();
}

class _CurrencyStreamListenerState extends State<CurrencyStreamListener> {
  @override
  void initState() {
    widget.notificationStream.listen((CurrencyNotification data) {
      if (data is NotificationOfIncrease) {
        Scaffold.of(context).showSnackBar(
          SnackBar(
            duration: Duration(seconds: 1),
            content: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text('Earned Currency'),
              ],
            ),
          ),
        );
      }
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}

Таким образом, я могу вкладывать этот виджет везде, где у меня есть доступ к потоку Blo c, поэтому, возможно, в каком-то классе Provider или Consumer ,

0 голосов
/ 30 января 2020

Изучив StatefulWidget еще немного, я вижу, что у нас на самом деле есть есть доступ к BuildContext context в initState. Вариант № 2, следовательно, жизнеспособен в конце концов. Это позволяет нам сохранять логику c и просматривать отдельно, а также поддерживать шаблон, согласно которому данные передаются только из BLo C в виджет с использованием потоков.

Чтобы повторить решение: BLo C может предоставить поток данных (например, код ошибки), на который виджет с отслеживанием состояния может подписаться в State initState. Слушатель может использовать свойство context, чтобы показать диалоговое окно, когда поток передает некоторые данные.

...