Flutter.io(Dart) - 如何计算符合特定条件的Firebase查询返回的项目

时间:2018-01-03 04:29:36

标签: firebase dart flutter

在屏幕中,Firebase列表已将逻辑应用于

  1. 反应性地检测小部件的蓝色
  2. 隐藏蓝色小部件
  3. 显示非蓝色小部件
  4. 我想要计算蓝色小部件。

    这样做的最佳方式是什么?

    return new StreamBuilder<int>(
        stream: subscribeMyThings(thing.id),
        builder: (context, thingsSnapshot) {
            return new FirebaseAnimatedList(
              query: getThings(thing.id),
              itemBuilder: (context, snapshot, animation, index) {
                return new ReactiveWidget<int>(
                  reactiveRef: getThingBlueness(snapshot.key),
                  widgetBuilder: (checkBlueness) {
                    // code to check blueness here
    
                    // if Thing is blue, place empty container
                    if (thingIsBlue) {
                      return new Container();
                      // *** how do I count these??? ***
                    }
    
                    // or, if Thing is NOT blue
                    return new Thing(thing.id);
                    );
                  },
                );
            );
          }
    

1 个答案:

答案 0 :(得分:3)

我认为你没有从正确的角度来看问题,加上标题是误导性的。

您可能无意计算屏幕上显示的窗口小部件,而是计算符合某些条件的Firebase数据库条目的子集。 这在Flutter中有很大的不同,因为计算小部件通常涉及渲染树,布局和图形,而看起来你想要解决数据问题。

如果我是对的,那么你可能会考虑在你的数据库中有一个索引来跟踪蓝色项目的数量并在另一个streambuilder中收听它。

长话短说,您可能想要保留地图&lt; id,blueness&gt ;,在构建时更新每个元素,并在需要计数时迭代地图。

// somewhere in your outer scope
Map<int, bool> _bluenessMap = new Map<int, bool>();

  return new StreamBuilder<int>(
    stream: subscribeMyThings(thing.id),
    builder: (context, thingsSnapshot) {
        return new FirebaseAnimatedList(
          query: getThings(thing.id),
          itemBuilder: (context, snapshot, animation, index) {
            return new ReactiveWidget<int>(
              reactiveRef: getThingBlueness(snapshot.key),
              widgetBuilder: (checkBlueness) {
                // code to check blueness here


                // ----------------------------
                // before return let us update the map

                _bluenessMap[thing.id] = thingIsBlue

                // ----------------------------

                // if Thing is blue, place empty container
                if (thingIsBlue) {
                  return new Container();
                }

                // or, if Thing is NOT blue
                return new Thing(thing.id);

                );
              },
            );
        );
      }

  // call me when you want to count
  int fancyBlueCounter(){
      int result = 0;
      for(bool isBlue in _bluenessMap.values){
        if(isBlue) result += 1;
      }
      return result;
  }

修改

由于该问题的作者确认这是一个“数据问题”,我觉得建议采用另一种(可能更好的)方式来解决它。

聚合或索引(在我看来)是解决问题的正确方法。每当有人触摸 Thing 时,取决于其 blueness ,它会刷新DB中有目的地创建的聚合(实际上也是一个简单的数据条目 count )。您可以使用事务进行任何功能编辑事务,更新蓝色计数,或使用云功能 (请参阅doc here)监听更改事件(创建,删除和编辑)以及更新计数