Поток уже прослушан, ошибка после смены экранов

Я применяю шаблон Bloc в своем приложении, и у меня возникли проблемы при изменении экрана с помощью нижней навигации.

Я пытался сделать Stream Broadcast, но после смены экрана данные пропадают.

Вот мой домашний класс, он представляет собой домашний экран.

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final DepartmentBloc departmentBloc = BlocProvider.getBloc<DepartmentBloc>();
  final PromotionProductBloc promotionProductBloc = BlocProvider.getBloc<PromotionProductBloc>();

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      physics: BouncingScrollPhysics(),
      child: SafeArea(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            CustomText(
              text: "Promoções",
              fontSize: 20.0,
              padding: EdgeInsets.only(left: 12.0),
            ),
            StreamBuilder(
              stream: promotionProductBloc.outPromotionProducts,
              builder: (context, snapshot) {
                if (snapshot.hasData)
                  return Container(
                    height: 230.0,
                    child: ListView.builder(
                      padding: EdgeInsets.only(
                          left: 12.0, right: 12.0, bottom: 10.0),
                      itemBuilder: (context, index) {
                        return PromotionProductCard(snapshot.data[index]);
                      },
                      itemCount: snapshot.data.length,
                      scrollDirection: Axis.horizontal,
                      physics: BouncingScrollPhysics(),
                    ),
                  );
                else
                  return Container(
                    height: 200.0,
                  );
              },
            ),
            CustomText(
              text: "Categorias",
              fontSize: 20.0,
              padding: EdgeInsets.only(left: 12.0, top: 20.0, bottom: 10.0),
            ),
            StreamBuilder(
              stream: departmentBloc.outDepartments,
              builder: (context, snapshot) {
                if (snapshot.hasData)
                  return Container(
                    height: 120.0,
                    child: ListView.builder(
                      padding: EdgeInsets.only(left: 12.0, right: 12.0),
                      itemBuilder: (context, index) {
                        return CategoryCard(snapshot.data[index]);
                      },
                      itemCount: snapshot.data.length,
                      scrollDirection: Axis.horizontal,
                      physics: BouncingScrollPhysics(),
                    ),
                  );
                else
                  return Container(
                    height: 100.0,
                  );
              },
            ),
          ],
        ),
      ),
    );
  }

Вот класс, который обращается к Сервису для получения данных и открывает выход для Stream.

class DepartmentBloc extends BlocBase {

  DepartmentService departmentService;

  List<Department> departments;

  final StreamController<List<Department>> _departmentController = StreamController<List<Department>>();
  Stream<List<Department>> get outDepartments => _departmentController.stream;

  DepartmentBloc() {
    departmentService = DepartmentService();
    getAll();
  }

  void getAll() async {
    departments =  await departmentService.getAll();
    _departmentController.sink.add(departments);
  }

  @override
  void dispose() {
    _departmentController.close();
    super.dispose();
  }
}

PromotionProductBloc - это то же самое, что и DepartmentBloc, он только изменяет доступ к сервису.

Я использую нижнюю навигацию, после перехода на другой экран и обратно появляется следующая ошибка: Stream уже прослушан.


person Filippe Oliveira Da Silva Rodr    schedule 14.06.2019    source источник


Ответы (1)


Пытаться

  final StreamController<List<Department>> _departmentController = StreamController.broadcast<List<Department>>();

Похоже, вы используете один контроллер потока подписки. Их можно послушать только один раз. Их преимущество в том, что первый слушатель получит те события, которые были сгенерированы, прежде чем подписаться на него. Широковещательные потоки не гарантируют такого поведения, но на них можно подписаться несколько раз.

person Daniel V.    schedule 15.06.2019
comment
И в дополнение к вашему ответу, еще одна хорошая практика, в будущем, конечно, загляните в библиотеку RxDart. Изучение трех предметов еще больше облегчит его знания - person Fellipe Malta; 15.06.2019
comment
Трансляция заставляла данные исчезать, когда я меняю экран. Думаю, мне удалось решить эту проблему следующим образом: final _departmentController = BehaviorSubject ‹List ‹Department›› .seeded (List ‹Department› ()); - person Filippe Oliveira Da Silva Rodr; 15.06.2019