StreamBuilder не перестраивается на новое событие в потоке - PullRequest
0 голосов
/ 23 мая 2019

Мой StreamBuilder в поле зрения:

Widget build(BuildContext context) {
    print("rebuilding..."); // as of now this gets called only on view initialization and never again - i.e. not on new events going through alarmController.stream

    return StreamBuilder(
        stream: widget.bloc.alarmController.stream,
        initialData: Alarm(''),
        builder: (BuildContext context, AsyncSnapshot<Alarm> snapshot) {
          if (!snapshot.hasData) {
            return Center(
              child: Text(StringLiterals.NO_ALARM_DATA_MSG))
            );
          }

          return Switch(
                  activeColor: Colors.red,
                  value: snapshot.data.status == 'Started',
                  onChanged: (bool _value) {
                    _newAlarmValue = _value;
                    _askAlarmConfirmation();
                  }));
        });
  }

мясо моего блока:

AlarmBloc(this.Api) {
    getAlarm();
}
  getAlarm() async {
    Alarm response = await Api.getAlarmStatus();
    alarmController.sink.add(response); // here im adding new event, therefore streambuilder should rebuild, right?
}

И, наконец, код, который я вызываю, чтобы инициировать новое событие (в данном случае это сообщение firebase):

if(_message.notification.body.contains("Alarm") && IS_LOGGED_IN == true) {
   alarmBloc.getAlarm();
 }

Таким образом, проблема в том, что StreamBuilder не перестраивается, когда новое событие проходит через alarmController.stream. В чем может быть причина?

Ответы [ 2 ]

0 голосов
/ 27 мая 2019

Проблема заключалась в том, что я неправильно создавал свой BLOC (второй) и работал над вторым параллельным потоком, и поэтому он не был передан StreamBuilder.

0 голосов
/ 24 мая 2019

Ваш блок должен быть типом Stream. Тот же тип потока, что и у вашего StreamBuilder. Например, ваш блок должен быть Stream<Alarm>. В противном случае stream: widget.bloc.alarmController.stream, будет вызываться только один раз и не будет действовать как асинхронный поток данных.

Ваш Streambuilder должен проверить состояние соединения

Widget build(BuildContext context) {
    print("rebuilding..."); // as of now this gets called only on view initialization and never again - i.e. not on new events going through alarmController.stream

    return StreamBuilder<Alarm>(
        stream: widget.bloc.alarmController.stream,
        initialData: Alarm(''),
        builder: (BuildContext context, AsyncSnapshot<Alarm> snapshot) {
          if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
      switch (snapshot.connectionState) {
        case ConnectionState.waiting:
          return Text('Loading...'); 
        default: 
          if (!snapshot.hasData) {
             return Center(
                child: Text(StringLiterals.NO_ALARM_DATA_MSG))
             );
          }

         return Switch(
              activeColor: Colors.red,
              value: snapshot.data.status == 'Started',
              onChanged: (bool _value) {
                _newAlarmValue = _value;
                _askAlarmConfirmation();
              }));
      }

Вот другие типы состояний соединения, которые вы можете проверить:

async.dart

    enum ConnectionState {
  /// Not currently connected to any asynchronous computation.
  ///
  /// For example, a [FutureBuilder] whose [FutureBuilder.future] is null.
  none,

  /// Connected to an asynchronous computation and awaiting interaction.
  waiting,

  /// Connected to an active asynchronous computation.
  ///
  /// For example, a [Stream] that has returned at least one value, but is not
  /// yet done.
  active,

  /// Connected to a terminated asynchronous computation.
  done,
}
...