flutter_blo c подвиджет закрывает blo c родительского виджета - PullRequest
0 голосов
/ 06 февраля 2020

Я использую пакет flutter_blo c.

У меня есть страница с панелью вкладок. Страница создает блок blo c и предоставляет его виджетам, которые используются в качестве содержимого вкладки.

class _MyScreenState extends State<MyScreen> {
  MyBloc _myBloc;
  ...

  Widget _buildTabBar() {
  ...

    var children = [
    _buildFirstTab()
    _buildSecondTab(),
    ];

    return WillPopScope(
      onWillPop: _onWillPop,
      child: DefaultTabController(
      length: children.length,
      child: Scaffold(
        appBar: PreferredSize(
            preferredSize: Size.fromHeight(75.0),
            child: AppBar(
              bottom: TabBar(isScrollable: true, tabs: tabs),
            )),
        body: TabBarView(
          children: children,
        ),
      ),
    ),
  );
  }
..
}

Widget _buildSecondTab() {
  if (_myBloc == null) {
    _myBloc = MyBloc(<..initialdata..>);
  }
  _myBloc.add(LoadServerDataEvent());

  return BlocProvider<MyBloc>(create: (_) => _myBloc, child: SecondTab());
}

Виджет на второй вкладке получает блок blo c от BlocProvider и использует его.

class _SecondTabState extends State<SecondTab> {
  MyBloc _myBloc;

  @override
  void initState() {
    _myBloc = BlocProvider.of<MyBloc>(context);
    super.initState();
  }

Моя проблема в том, что блок автоматически закрывается, когда я переключаюсь между вкладками.

Это немного странно, потому что блок все еще используется на странице.

1 Ответ

0 голосов
/ 06 февраля 2020

Что ж, вы делаете неправильно несколько вещей:

  1. , если вы хотите, чтобы ваш bloc был доступен как на первой, так и на второй вкладке, вам следует обернуть всю панель вкладок этим,
  2. очень странно, что вы держите экземпляр blo c в _MyScreenState и делаете магию c с ленивым инициатором сингелтоне if (_myBloc == null) _myBloc = MyBloc(),
  3. _myBloc.add(LoadServerDataEvent()); в большинстве случаи должны запускаться в initState методе _SecondTabState.
  4. Это очень необычно, что bloc получает исходные данные из пользовательского интерфейса. Если вы хотите построить свою архитектуру, используя blocs, эти исходные данные должны поступить из другого bloc.

Но если вы хотите предоставить существующий bloc для второй вкладки и не допустить его будучи закрытым, вы должны использовать:

BlocProvider.value(
  value: _myBloc,
  child: SecondTab(),
);

Вместо:

BlocProvider<MyBloc>(create: (_) => _myBloc, child: SecondTab());
...