Как использовать потоковую подписку с помощью Flutter Cubit

#flutter #dart #flutter-bloc #dart-async #dart-stream

Вопрос:

У меня проблема в том, что подписка на поток на локоть не прослушивает состояние излучения локтя. Вот пример того, как я реализовал их в своем коде.

Это тот локоть, который я хочу послушать

 class ButtonPressCubit extends Cubit<ButtonState> {

  ButtonPressCubit() : super(ButtonNotPressed());

  void emitButtonOnePressed() => emit(ButtonOnePressed());
  void emitButtonTwoPressed() => emit(ButtonTwoPressed());

}
 
 part of 'internet_cubit.dart';

@immutable
abstract class ButtonState {}

class ButtonNotPressed extends ButtonState {}

class ButtonOnePressed extends ButtonState {}

class ButtonTwoPressed extends ButtonState {}

 

Это локоть, на который я хочу подписаться, локоть, который я хочу слушать.

 class CounterCubit extends Cubit<CounterState> {
  final ButtonPressCubit buttonPressCubit;
  StreamSubscription buttonPressStreamSubscription;
  CounterCubit({@required this.internetCubit})
      : super(CounterState(counterValue: 0, wasIncremented: false)) {
    buttonPressStreamSubscription = buttonPressCubit.listen(print);
  }

  void increment() => emit(
      CounterState(counterValue: state.counterValue   1, wasIncremented: true));

  void decrement() => emit(CounterState(
      counterValue: state.counterValue - 1, wasIncremented: false));

  @override
  Future<void> close() {
    buttonPressStreamSubscription.cancel();
    return super.close();
  }
}
 

После этого я вызвал кнопку Presscubit, emitButtonOnePressed() как показано ниже.

 MaterialButton(
  child: Text('Buton 2'),
  onPressed: () {
    BlocProvider.of<ButtonPressCubit>(context)
      .emitButtonTwoPressed();
    },
),
 

Но это не работает. как это исправить, чтобы получить состояние локтя.

Комментарии:

1. вы зарегистрировали Локоть на этой Странице?

2. Нет, как это сделать?

Ответ №1:

Если вы не зарегистрировали локоть этого виджета до его запуска, вам следует это сделать

это все равно что сказать флаттеру, что этот локоть предназначен для этой страницы, и для этого есть несколько подходов

во-первых: если у вас более одного блока или

  MultiBlocProvider(
      providers: [
        //other Blocs or Cubits
        BlocProvider<XCubit>(
          create: (BuildContext context) => XCubit(),
          child: XWidget(),
        ),
        //other Blocs or Cubits
      ],
      child: MaterialApp(),....);
 

Второе: как в документации

 class _AppState extends State<App> {
  final UserRepository _userRepository = UserRepository();
  AuthenticationBloc _authenticationBloc;

  @override
  void initState() {
    super.initState();
    _authenticationBloc = AuthenticationBloc(userRepository: _userRepository);
    _authenticationBloc.dispatch(AppStarted());
  }

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      bloc: _authenticationBloc,
      child: MaterialApp(
        home: BlocBuilder(
          bloc: _authenticationBloc,
          builder: (BuildContext context, AuthenticationState state) {
            //here is your widget you want to run
            return Container();
          },
        ),
      ),
    );
  }
 

но помните, что вы должны сделать это перед запуском/запуском вашего виджета

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

это еще одна вещь, о которой вы должны заботиться, но эта, если вы используете блок, а не локоть, вы реализуете блок

{Слушатель,конструктор..}в вашем виджете, чтобы вы могли видеть изменения

   BlocBuilder<AddNewStudentBloc, AddNewStudentState>(
          builder: (context, state) {
//here you do respond for the state like 
// if State is Error return ErrorWidget
// else if the state is Success return SuccessWidget
// and so on....
return Container(); },
    );