为什么子窗口小部件StreamBuilders没有收到错误?

时间:2019-03-31 14:48:50

标签: dart flutter bloc rxdart

我在为RxDart挣扎(也许只是直接进行Rx编程)。我目前有一个有状态的小部件,它在didChangeDependencies()中调用我的bloc。该调用消失,并通过http请求获取数据,并将其添加到流中。我正在使用BehaviorSubject,它工作正常。我有使用StreamBuilders的子小部件,并且它们获取数据没有问题。我的问题在于处理错误。如果我的http请求失败,我用addError('whatever error')混合流,但是我的子窗口小部件的StreamBuilder没有收到该错误。它什么也没有。

所以我有几个问题。

  1. 那是预期的吗?
  2. 是否应在StreamBuilder中不进行错误处理?理想情况下,如果出现问题,我想在UI中显示某些内容,因此不确定其他方法。
  3. 我可以使我的孩子小部件成为有状态的,并使用stream.listen。我确实在那儿收到了错误,但是拥有StreamBuilder和StreamBuilder似乎是过大了。
  4. 我在这里是否缺少有关流和错误处理的基本知识?

这是我的集团:

final _plans = BehaviorSubject<List<PlanModel>>();
Observable<List<PlanModel>> get plans => _plans.stream;

fetchPlans() async {
    try {
        final _plans = await _planRepository.getPlans();
        _plans.add(_plans);
    }
    on AuthenticationException {
        _plans.addError('authentication error');
    }
    on SocketException {
        _plans.addError('no network connection');
    }
    catch(error) {
        _plans.addError('fetch unsuccessful');
    }
}

简化的父窗口小部件:

class PlanPage extends StatefulWidget {
  @override
  PlanPageState createState() {
    return new PlanPageState();
  }
}

class PlanPageState extends State<PlanPage> {

  @override
  void didChangeDependencies() async {
    super.didChangeDependencies();
    var planBloc = BaseProvider.of<PlanBloc>(context);
    planBloc.fetchPlans();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar( title: const Text('Your Plan') ),
        body: PlanWrapper()
    );
  }
}

带有StreamBuilder的简化子小部件:

class PlanWrapper extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    var planBloc = BaseProvider.of<PlanBloc>(context);

    return StreamBuilder(
      stream: planBloc.plans,
      builder: (BuildContext context, AsyncSnapshot<List<PlanModel>> plans) {
        if (plans.hasError) {
          //ERROR NEVER COMES IN HERE
          switch(plans.error) {
            case 'authentication error':
              return RyAuthErrorCard();
            case 'no network connection':
              return RyNetworkErrorCard();
            default: 
              return RyGenericErrorCard(GeneralException().errorMessages()['message']);
          }
        }
        if (plans.hasData && plans.data.isNotEmpty) {
          return ListView(
            physics: const AlwaysScrollableScrollPhysics(),
            children: _buildPlanTiles(context, plans.data)
          );
        }
        return Center(child: const CircularProgressIndicator());
      }
    );
  }
}

1 个答案:

答案 0 :(得分:0)

RxDart GitHub(https://github.com/ReactiveX/rxdart/issues/227)中与此有关。 BehaviorSubject没有向新的侦听器重放错误。

它已在0.21.0版中修复。 “突破性的改变:如果最后一个事件也是一个错误,BehaviorSubject现在将发出一个错误。在侦听之前发生错误时,该错误不会通知订阅者。”