【问题标题】:StreamBuilder is not rebuilding on new event in streamStreamBuilder 不会在流中的新事件上重建
【发布时间】:2019-10-10 05:06:48
【问题描述】:

我的 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();
 }

所以问题是当新事件通过alarmController.stream 时StreamBuilder 不会重建。可能是什么原因?

【问题讨论】:

  • 尝试通过在StreamBuilder 中添加您的打印语句来进行测试。 AFAIK 它不会强制整个小部件重建。
  • 我假设您使用的是 rxDart,所以请告诉我您使用的是哪种流控制器? PublishSubject 还是 BehaviorSubject?
  • 这是 BehaviourSubject @MarcosBoaventura

标签: dart flutter rxdart stream-builder


【解决方案1】:

您的 bloc 必须是 Stream 类型。与您的 StreamBuilder 相同的流类型。例如,您的集团需要是Stream&lt;Alarm&gt;。否则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,
}

【讨论】:

  • 不幸的是,事实并非如此。连接没有被终止,即使是 StreamBuilder 类型,因为它仍然没有在新事件被添加到接收器时重建小部件......
  • 流可能很棘手。我们可以为您检查更多选项。我们需要重新配置调用流,而不是通过控制器发回“响应”。看起来 getAlarm 只是在构建时调用,而不是异步流式传输数据。首先你能告诉我你期望 getAlarm 的响应类型是什么?
【解决方案2】:

问题是我错误地实例化了我的 BLOC(第二个)并处理了第二个并行流,因此不是传递给 StreamBuilder 的那个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-24
    • 2019-11-03
    • 2020-03-26
    • 2021-02-21
    • 2021-10-27
    • 2023-04-10
    • 2019-12-31
    • 1970-01-01
    相关资源
    最近更新 更多