如何将未来的结果与扑朔迷离的流联系起来?

时间:2019-05-22 19:43:11

标签: dart flutter stream future

我正在尝试从数据库获取数据,并使用流将该数据传输到屏幕。 我使用FutureBuilder完成了该解决方案的工作,但我需要使用streambuilder 谁能帮我找到问题。 我有一种从数据库获取数据的方法

Future<List<CementSandAggregateView>> getAllRatios() async{
   List<CementSandAggregateView> ratioList = new List();

    var types = await ratioRepository.getAll();
    for(int i = 0 ; i < types.length ; i ++){

      CementSandAggregateView view = new CementSandAggregateView();

      String cementRatio = types[i].cement.floor() < types[i].cement ? types[i].cement.toStringAsFixed(1):types[i].cement.toStringAsFixed(0);
      String sandRatio = types[i].sand.floor() < types[i].sand ? types[i].sand.toStringAsFixed(1):types[i].sand.toStringAsFixed(0);
      String aggregateRatio = types[i].aggregate.floor() < types[i].aggregate ? types[i].aggregate.toStringAsFixed(1):types[i].aggregate.toStringAsFixed(0);

      view.ratio = "$cementRatio:$sandRatio:$aggregateRatio (${types[i].name})";
      view.id = types[i].id;
      view.name = types[i].name;
      print(view.ratio);
      ratioList.add(view);
    }

    return ratioList;
  }

我想使用流

发送此数据
class CementSandAggregateMixBloC {
    BehaviorSubject<Future<List<CementSandAggregateView>>> _cSAMixController;
    BLoCProvider provider;
  CementSandAggregateMixBloC(){
    provider = new BLoCProvider();
    _cSAMixController = new BehaviorSubject<Future<List<CementSandAggregateView>>>();

    _cSAMixController.add(provider.getAllRatios());
  }

  Observable<Future<List<CementSandAggregateView>>> inputObservable() => _cSAMixController.stream;

    void dispose() {
    _cSAMixController.close();
  }
}

在我的屏幕上,我使用streambuilder

Widget _buildBottomNavigationBar1() {
    List<BottomNavigationBarItem> items = List();

    return StreamBuilder(
      stream: _rationBloC.inputObservable(),
      builder: (context,
          AsyncSnapshot<Future<List<CementSandAggregateView>>> snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.hasData) {
            snapshot.data.then((onValue) => {
                  onValue.forEach((mix) => {})
                });

            return BottomNavigationBar(
                items: items,
                currentIndex: _selectedRatio,
                fixedColor: Theme.of(context).buttonColor,
                onTap: _onItemTapped);
          } else {
            return new Center(
              child: new CircularProgressIndicator(),
            );
          }
        } else {
          return new Container(width: 0.0,height: 0.0,);
        }
      },
    );
  }

但是数据没有显示在屏幕上

我尝试了这个solution,但没有机会!

有人可以帮助我将将来的结果转换为流吗?

谢谢。

2 个答案:

答案 0 :(得分:1)

实现这一目标的简单方法是await,以便将来完成,然后将数据放入流中。

在您的集团课堂中:

void _init() async {
   List<CementSandAggregateView> data = await provider.getAllRatios();
   _cSAMixController.add(data);
}

CementSandAggregateMixBloC(){
    provider = new BLoCProvider();
    _cSAMixController = BehaviorSubject< List<CementSandAggregateView> >();
    _init();
  }

答案 1 :(得分:0)

我认为_init()应该在initState()的{​​{1}}方法中调用,或者在StatefulWidgetinitState方法中使用此代码。

build

这意味着在渲染第一帧之后即WidgetBinding.instance.addPostFrameCallback(() => _init()); 之后调用该过程。