对 Flutter 应用程序的 getX dart 包中的 RxList 进行排序

Posted

技术标签:

【中文标题】对 Flutter 应用程序的 getX dart 包中的 RxList 进行排序【英文标题】:Sort RxList from getX dart package for Flutter app 【发布时间】:2020-12-07 22:47:27 【问题描述】:

我无法按给定属性对可观察的 RxList 进行排序。当我使用 BloC 方法时,排序工作正常,使用一个简单的列表。

最近我将状态管理更改为 GetX (https://github.com/jonataslaw/getx) 包,因为我看到了几个优点(不需要上下文、转换到页面等)。

这里有两个场景,我的不好,前面没有解释,我放小黄瓜的

场景 1

Given user in Posts Screen
When user Pull down to get Newest posts
Then user get the newly fetched posts on top of the previous loaded list

场景 2:

Given user in Posts Screen
When user reaches the end of the list
Then user get more posts at the end of the previous loaded list

post_model.dart

class Post 
  final int id;
  final String title;
  final DateTime date;
  final User user;

Post(
    @required this.id,
    @required this.title,
    @required this.date,
    this.user);
 

post_controller.dart

import 'dart:async';

import 'package:get/state_manager.dart';
import 'package:blog/models/post.dart';
import 'package:blog/services/posts_api.dart';

class PostsController extends GetxController 
  int _page = 0;

  ---------HERE OBS LIST-----------
  RxList posts = [].obs;

  @override
  void onReady() 
    super.onReady();
    this.loadPosts();
  

  Future<void> loadPosts(isRefreshLoad = false) async 
    int pager;
    if (isRefreshLoad) 
      pager = 1;
     else 
      increment();
      pager = this._page;
    

    Map<String, String> arguments = 'page': '$pager';
    final List<Post> newPosts =
        await PostsApi.instance.getPosts(arguments: arguments);

    // remove duplicates
    posts.addAll(
      newPosts.where(
        (newPosts) => posts.every((post) => newPosts.id != post.id),
      ),
    );

    //----------HERE'S THE EXCEPTION----------
    posts.sort((a, b) => b.id.compareTo(a.id));
    update(['posts']);
  

错误

flutter: [GETX] PostsController has been initialized
[VERBOSE-2:ui_dart_state.cc(166)] Unhandled Exception: type 'Post' is not a subtype of type 'List<dynamic>'
#0      RxList.remove 
package:get/…/rx/rx_impl.dart:333

PostsScreen.dart

Scaffold(
                backgroundColor: Color.fromRGBO(58, 66, 86, 1.0),
                appBar: AppBarWidget(
                  drawerOpen: drawerPosition,
                  appBarVisible: _isVisible,
                  drawerVisible: true,
                ),
                body: ColorfulSafeArea(
                  overflowRules: OverflowRules.only(left: true, bottom: true),
                  child: GetBuilder<PostsController>(
                    id: 'posts',
                    init: PostsController(),
                    builder: (_postsController) 
                      _postsControllerGlobal = _postsController;
                      // Scenario 1 - Triggers when user pull down to get new posts
                      return RefreshIndicator( 
                        onRefresh: () 
                          return _postsController.loadPosts(
                              isRefreshLoad: true);
                        ,
                        child: StreamBuilderWidget(
                          stream: _postsController.posts.stream,
                         // Scenario 2 Triggers when scroll controller reaches end of list
                          scrollController: _scrollController,                               isDrawerOpen: _isDrawerOpen,
                          widgetType: 'PostItemWidget',
                        ),
                      );
                    ,
                  ),
                ),
              ),

----enter code here------

我需要一种方法,在将获取的帖子添加到流中后,始终按日期 desc 顺序重新排序获取的帖子列表,无论触发器是 PullDown 还是到达列表的最终末尾,以便始终显示项目按已发布顺序。

希望有人能帮帮我。

【问题讨论】:

【参考方案1】:

经过几天的尝试,我发现它要简单得多,而且由于我缺乏知识。

由于列表是可观察的,只需将其转换为列表即可完成排序:

普通列表

newPosts.sort((a, b) => b.date.compareTo(a.date));

可观察列表

newPosts.toList().sort((a, b) => b.date.compareTo(a.date));

谢谢!

【讨论】:

【参考方案2】:

首先订购您的清单,然后添加它

final List<Post> newPosts =
        await PostsApi.instance.getPosts(arguments: arguments);

//----------Try this---------
newPosts.sort((a, b) => b.id.compareTo(a.id));
    
// remove duplicates
    posts.addAll(
      newPosts.where(
        (newPosts) => posts.every((post) => newPosts.id != post.id),
      ),
    );

【讨论】:

您好,感谢您的回答,在原始帖子中添加了更多信息。您的回答不会涵盖到场景(再次道歉应该早点添加它们)。场景 1,您的重播会将它们添加到列表的末尾。我的目标是将它们添加到列表顶部,因为我正在获取新添加的帖子到列表中,而不是以前的帖子。再次感谢

以上是关于对 Flutter 应用程序的 getX dart 包中的 RxList 进行排序的主要内容,如果未能解决你的问题,请参考以下文章

Flutter GetX基础教程(十二):RxList、Rx([])、.obs对比分析

Docker 中用于 Web 上 Flutter 的 Dart 服务器

在 Flutter 中,我如何使用 API 和 GetX 在 JSON 中获取数据

Flutter Getx - 更新子列表中的项目不是反应性的

Flutter视频播放器,简洁!

在 Flutter 使用 GetX 对话框