缓存并将缓存的数据提供给StreamBuilder Flutter

时间:2019-05-13 03:26:00

标签: dart flutter

我目前正在使用StreamBuilderCloud Firestore提取数据,并且一切正常,但是我遇到了问题,因为从数据库中提取数据时,我必须对数据执行一些异步操作为了过滤数据,每当用户进入不同的页面并返回首页时,页面都会刷新自身,执行不需要的异步操作。

异步功能需要一点时间,因此我试图使用缓存来存储开始时加载的数据,并且仅在刷新时才重新加载数据。我碰到了这个post,它显示了简单缓存的示例。

这是我的实现方式

class FetchObjects {


  Duration _cacheValidDuration;
  DateTime _lastFetchTime;

  List<DataModel> currentData = [];

  FetchObject() {
    _cacheValidDuration = Duration(minutes: 30);
    _lastFetchTime = DateTime.fromMillisecondsSinceEpoch(0);

    fetchtheData();
  }

  Future<void> refereshData() async {
    await getFromDataBase();
  }

  Future<List<DataModel>> fetchtheData({bool forceRefresh = false}) async {
    bool shouldRefreshFromApi = (null == currentData ||
        currentData.isEmpty ||
        null == _lastFetchTime ||
        _lastFetchTime.isBefore(DateTime.now().subtract(_cacheValidDuration)) ||
        forceRefresh);

    if (shouldRefreshFromApi) {
      await refereshData();
    }

    return currentData;
  }

  void getDataFromDataBase() async {
    await Firestore.instance...getDocuments()
        .then((onValue) {
      filterData(onValue.documents);
    });
  }

  void filterData(List potentialData) async {
    for (DocumentSnapshot docs in potentialData) {


       String criteria = perfomAsyncOperation(doc);

        if (if passes Creteria) {
          Model newModel = new Model.from(docs);
            this.currentData.add(newModel);
        }
      }
    }
  }
}

我现在正尝试在StreamBuilder中使用此类的结果,如下所示:

  @override
  void initState() {

    backEndCall = new FetchObjects();
  }


@override
  Widget build(BuildContext context) {
    return Scaffold(
        key: scaffoldKey,
        body: StreamBuilder<List<Model>>(
            stream: Stream.fromFuture(backEndCall.fetchtheData()),
            builder:
                (BuildContext context, AsyncSnapshot<List<model>> snapshot) {
                  print(" the data is "+snapshot.data.toString());
              if (snapshot.hasError) {
                return Text(snapshot.error);
              }
              if (snapshot.connectionState == ConnectionState.none) {
                return Text("Error");
              }

              if (!snapshot.hasData &&
                  snapshot.connectionState == ConnectionState.waiting &&
                  snapshot.data == null) {
                return Container(
                  alignment: Alignment.center,
                  child: Text(
                    "no data",
                    textAlign: TextAlign.center,
                    style: TextStyle(),
                  ),
                );
              }
              if (snapshot.connectionState == ConnectionState.active) {
                return Container(
                  // color: Colors.pink,
                  alignment: Alignment.center,
                  child: Text(
                    "There is data",
                    textAlign: TextAlign.center,
                    style: TextStyle(),
                  ),
                );


              } else {
                print(snapshot.connectionState);
                return Container(
                    child: Center(
                        child: CircularProgressIndicator();
              }
            }));
  }

到目前为止,我没有从FetchObjects类中检索数据的任何运气。它可以很好地获取数据,但是我无法在StreamBuilder中获取它。关于其他实现或对此实现的修复有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我最终使用了完全不同的方法。 当您导航到新页面时,我确保该页面保持活动状态。我通过使用AutomaticKeepAliveClientMixin扩展类并覆盖

来实现此目的
@override
  bool get wantKeepAlive => true;

示例

class SampleClassState extends State<SampleClass> with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

}

请参见this。这样,仅在刷新时才重新加载页面。