那么在Flutter中进行缓存的最简单方法是什么? [英] So what is the simplest approach for Caching in Flutter?

查看:1169
本文介绍了那么在Flutter中进行缓存的最简单方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该应用程序是一个简单的新闻阅读器,它显示WordPress帖子,没有花哨,不使用BLOC,继承的Widget,Firebase。
我希望它即使在用户脱机时也显示缓存的数据(最新的10条帖子)。

The app is a simple news reader which shows WordPress posts, nothing fancy, not using a BLOC, inherited Widget, Firebase. I want it to show the cached data(which is the latest 10 posts) even when the user is offline.

因此,如果用户脱机,则显示Cached数据;

So if the user is offline show Cached data; or somehow default data is cached data.

从WP REST API
获取firstPost [Id]如果缓存的Json文件包含Post [id],则显示已缓存数据;
其他getPosts();并显示加载指示器。也请更新本地JSON文件。

get the firstPost[Id] from WP REST API If the cached Json file contains Post[id] then show cached data; Else getPosts(); and show loading indicator. also please update the local JSON file.

获取JSON数据的代码:

code to get JSON data:

// Function to fetch list of posts
 Future<String> getPosts() async {
 var res = await http
    .get(Uri.encodeFull(apiUrl + "posts?_embed&per_page=10"), //TODO make it unlimited
        headers: {"Accept": "application/json"});

setState(() {
  var resBody = json.decode(res.body);

  posts = resBody;
});

return "Success!";
}

获取帖子和显示加载指示器的未来:

the future to get posts and shows loading indicator :

  body: FutureBuilder<List<String>>(
      future: getPosts(),
      builder: (context, snapshot) {
        if (snapshot.hasError) print(snapshot.error);

        return snapshot.hasData
            ? ListViewPosts(posts: snapshot.data)
            : Center(child: CircularProgressIndicator());
      },
    ),


推荐答案

基于时间的简单缓存不需要太多代码。

A simple time-based cache doesn't require much code.

这可能会帮助您。它使用 ScopedModel ,但是它很容易成为一个简单的类,尽管您必须删除 notifyListeners()调用或用您自己的机制替换它,如果您希望模型触发UI刷新。

This might help you out. It uses ScopedModel, but it could just as easily be a simple class, although you'd have to either remove the notifyListeners() call or replace it with your own mechanism if you want the model to trigger a refresh of the UI.

class MyModel extends Model{
    Duration _cacheValidDuration;
    DateTime _lastFetchTime;
    List<MyRecord> _allRecords;



    MyModel(){
        _cacheValidDuration = Duration(minutes: 30);
        _lastFetchTime = DateTime.fromMillisecondsSinceEpoch(0);
        _allRecords = [];
    }



    /// Refreshes all records from the API, replacing the ones that are in the cache.
    /// Notifies listeners if notifyListeners is true.
    Future<void> refreshAllRecords(bool notifyListeners) async{
        _allRecords = await MyApi.getAllRecords(); // This makes the actual HTTP request
        _lastFetchTime = DateTime.now();
        if( notifyListeners ) this.notifyListeners();
    }


    /// If the cache time has expired, or forceRefresh is true, records are refreshed from the API before being returned.
    /// Otherwise the cached records are returned.
    Future<List<MyRecord>> getAllRecords({bool forceRefresh = false}) async{
        bool shouldRefreshFromApi = (null == _allRecords || _allRecords.isEmpty || null == _lastFetchTime || _lastFetchTime.isBefore(DateTime.now().subtract(_cacheValidDuration)) || forceRefresh);

        if( shouldRefreshFromApi )
           await refreshAllRecords(false);

        return _allRecords;
    }
}

要从 MyModel中获取数据,用户界面仅调用 getAllRecords()。这将从内存中获取记录(即从 _allRecords )或触发刷新以进行HTTP调用并更新记录。缓存的数据将在30分钟后自动过期,并且如果您想强制刷新(例如,如果用户明确点击刷新按钮),则可以传递 forceRefresh:true

To get data from MyModel, the UI simply calls getAllRecords(). This will either fetch the records from memory (i.e. from _allRecords) or trigger a refresh which would make a HTTP call and update the records. The cached data automatically expires after 30 minutes, and if you want to force a refresh (for example if the user explicitly taps a refresh button), you can pass forceRefresh: true.

这篇关于那么在Flutter中进行缓存的最简单方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆