首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >流的颤振重装列表& RxDart

流的颤振重装列表& RxDart
EN

Stack Overflow用户
提问于 2018-06-19 18:10:16
回答 1查看 9.1K关注 0票数 9

在使用Streams和RxDart调用刷新指示器之后,我有一个关于如何重新加载列表的问题。

下面是我的模型课:

代码语言:javascript
复制
    class HomeState {

      List<Event> result;
      final bool hasError;
      final bool isLoading;

       HomeState({
        this.result,
        this.hasError = false,
        this.isLoading = false,
      });

      factory HomeState.initial() =>
          new HomeState(result: new List<Event>());
      factory HomeState.loading() => new HomeState(isLoading: true);
      factory HomeState.error() => new HomeState(hasError: true);

    }


    class HomeBloc {

      Stream<HomeState> state;
      final EventRepository repository;

      HomeBloc(this.repository) { 
        state = new Observable.just(new HomeState.initial());
      }

      void loadEvents(){
        state = new Observable.fromFuture(repository.getEventList(1)).map<HomeState>((List<Event> list){
          return new HomeState(
              result: list,
              isLoading: false 
          );    
        }).onErrorReturn(new HomeState.error())
        .startWith(new HomeState.loading());
      }

    }

我的小部件:

代码语言:javascript
复制
    class HomePageRx extends StatefulWidget {
      @override
      _HomePageRxState createState() => _HomePageRxState();
    }

    class _HomePageRxState extends State<HomePageRx> {
      HomeBloc bloc;

      _HomePageRxState() {
        bloc = new HomeBloc(new EventRest());
        bloc.loadEvents();
      }

      Future<Null> _onRefresh() async {
        bloc.loadEvents();
        return null;
      }

      @override
      Widget build(BuildContext context) {
        return new StreamBuilder(
            stream: bloc.state,
            builder: (BuildContext context, AsyncSnapshot<HomeState> snapshot) {
              var state = snapshot.data;
              return new Scaffold(
                body: new RefreshIndicator(
                  onRefresh: _onRefresh,
                  child: new LayoutBuilder(builder:
                      (BuildContext context, BoxConstraints boxConstraints) {
                    if (state.isLoading) {
                      return new Center(
                        child: new CircularProgressIndicator(
                          backgroundColor: Colors.deepOrangeAccent,
                          strokeWidth: 5.0,
                        ),
                      );
                    } else {
                      if (state.result.length > 0) {
                        return new ListView.builder(
                            itemCount: snapshot.data.result.length,
                            itemBuilder: (BuildContext context, int index) {
                              return new Text(snapshot.data.result[index].title);
                            });
                      } else {
                        return new Center(
                          child: new Text("Empty data"),
                        );
                      }
                    }
                  }),
                ),
              );
            });
      }
    }

问题是,当我执行拉式刷新列表时,UI不刷新(服务器被调用,刷新指示器的动画也被调用),我知道这个问题与流有关,但我不知道如何解决。

预期结果:在加载数据之前显示CircularProgressIndicator

有什么帮助吗?谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-19 18:27:30

不应该更改state的实例。

相反,您应该向可观察的对象提交一个新的值。这样,正在监听StreamBuilderstate将被通知一个新的值。

这意味着您不能只在内部拥有一个Observable实例,因为Observable没有任何方法来添加新值。所以你需要一个Subject

基本上,这会将您的Bloc更改为:

代码语言:javascript
复制
class HomeBloc {
  final Stream<HomeState> state;
  final EventRepository repository;
  final Subject<HomeState> _stateSubject;

  factory HomeBloc(EventRepository respository) {
    final subject = new BehaviorSubject(seedValue: new HomeState.initial());
    return new HomeBloc._(
        repository: respository,
        stateSubject: subject,
        state: subject.asBroadcastStream());
  }

  HomeBloc._({this.state, Subject<HomeState> stateSubject, this.repository})
      : _stateSubject = stateSubject;

  Future<void> loadEvents() async {
    _stateSubject.add(new HomeState.loading());

    try {
      final list = await repository.getEventList(1);
      _stateSubject.add(new HomeState(result: list, isLoading: false));
    } catch (err) {
      _stateSubject.addError(err);
    }
  }
}

另外,请注意loadEvent如何在异常情况下使用addError。而不是用HomeState来推动hasError: true

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50934582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档