Riverpod:摄取 REST API 的简单方法

2024-01-03

我目前正在构建一个应用程序,该应用程序摄取 WordPress REST API 来显示博客文章。在初始应用程序加载时,我希望它使用一种方法提取初始数据,然后通过用户交互提取更多帖子。我目前正在进行这项工作,但是,我的实现似乎很复杂,并且可能有一种更干净的方法来完成这项工作。我的实施基于此 GitHub 问题回复 https://github.com/rrousselGit/river_pod/issues/57#issuecomment-1012366576。我的代码如下所示:

In main.dart:

final blogRepository = FutureProvider((ref) async {
  final posts = await getPosts();
  return BlogService(posts);
      },
);

final blogProvider = StateNotifierProvider<BlogService, List<BlogPost>>((ref) => throw UnimplementedError(
    "Access to a [BlogService] should be provided through a [ProviderScope]."));

In blogservice.dart:

class BlogService extends StateNotifier<List<BlogPost>> {
  final List<BlogPost> _posts;
  BlogService(this._posts) : super(_posts);
  List<BlogPost> get posts => _posts;

  Future<void> morePosts(int length) async {
    Response response;
    var dio = Dio();
    response = await dio.get('https://wordpress-site.com/wp-json/wp/v2/posts/?offset=' + length.toString());
    var posts = (response.data as List);

    state = [...state, ...posts.map((post) => BlogPost.fromJson(post)).toList()];
  }
}

Future<List<BlogPost>> getPosts() async {
  Response response;
  var dio = Dio();
  response = await dio.get('https://wordpress-site.com/wp-json/wp/v2/posts/');
  var posts = (response.data as List);

  return posts.map((post) => BlogPost.fromJson(post)).toList();

}

我认为更好的方法是使用AsyncValue但是,我无法找到任何使用此 API 的良好参考实现。


这是一个使用的示例AsyncValue- 它消除了repository

让你的 service.dart 文件像这样:

final blogServiceProvider = Provider<BlogService>((ref) => BlogService());

class BlogService {
  Future<AsyncValue<List<BlogPost>>> getBlogPost() async {
    try {
      var dio = Dio();
      Response response = await dio.get('https://wordpress-site.com/wp-json/wp/v2/posts/');
      var posts = (response.data as List);
      List<BlogPost> list  = posts.map<BlogPost>((post) => BlogPost.fromJson(post)).toList();
      return AsyncData(list);
    } catch (e) {
      return AsyncError("Something went wrong");
    }
  }
}

你的提供者就像这样:

final blogNotifierProvider = StateNotifierProvider<BlogNotifier, AsyncValue<List<BlogPost>>>((ref){
  BlogService _service = ref.read(blogServiceProvider);
  return BlogNotifier(_service);
});

class BlogNotifier extends StateNotifier<AsyncValue<List<BlogPost>>> {
  BlogNotifier(this._service) : super(AsyncLoading()) {
    getPosts();
  }
  final BlogService _service;

  void getPosts() async {
    state = await _service.getBlogPost();
  }
}



编辑:要将现有帖子与新帖子合并,请尝试以下操作:

class BlogService {

  List<BlogPost> _posts = [];

  Future<AsyncValue<List<BlogPost>>> getBlogPost() async {
    try {
      var dio = Dio();
      Response response = await dio.get('https://wordpress-site.com/wp-json/wp/v2/posts/');
      var posts = (response.data as List);
      List<BlogPost> list  = posts.map<BlogPost>((post) => BlogPost.fromJson(post)).toList();
      _posts = list;
      return AsyncData(list);
    } catch (e) {
      return AsyncError("Something went wrong");
    }
  }

    Future<AsyncValue<List<BlogPost>>> morePosts() async {
    try {
      var dio = Dio();
      Response response = await dio.get('https://wordpress-site.com/wp-json/wp/v2/posts/?offset=' + length.toString());
      var posts = (response.data as List);
      List<BlogPost> list  = posts.map<BlogPost>((post) => BlogPost.fromJson(post)).toList();
      _posts.addAll(list);
      return AsyncData(_posts);
    } catch (e) {
      return AsyncError("Something went wrong");
    }
  }
}

通知者类将是:

class BlogNotifier extends StateNotifier<AsyncValue<List<BlogPost>>> {
  BlogNotifier(this._service) : super(AsyncLoading()) {
    getPosts();
  }
  final BlogService _service;

  void getPosts() async {
    state = await _service.getBlogPost();
  }

  void morePosts() async {
    state = await _service.morePosts();
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Riverpod:摄取 REST API 的简单方法 的相关文章