首页 > 解决方案 > Flutter中DataTable排序触发StreamBuilder再次取数据

问题描述

我有一个 DataTable,我在其中显示 Firestore 中的一些 UserData。但是当我使用 OnSort 实现排序时,我必须调用 setState,因为我必须存储 columnIndex 和升序标志,这会触发小部件重建,从而导致 StreamBuilder 再次获取所有数据。此外,由于在调用 StreamBuilder 后重新填充了列表,因此它也撤消了排序。

这是我的(相关)代码片段:

StreamBuilder(
            stream: UserData_StreamPublisher().getUserDataStream(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                usersData = snapshot.data as List<UserData>;
                return DataTable(
                  sortAscending: isAscending,
                  sortColumnIndex: sortColumnIndex,
                  columns: getColumns(columns),
                  rows: getRows(usersData),
                );
              } else {
                return CircularProgressIndicator();
              }
            })
class _UserData_PageState extends State<UserData_Page> {
  int? sortColumnIndex;
  bool isAscending = false;
  List<UserData> usersData = []; //To be read from Publisher->StreamBuilder
  void onSort(int columnIndex, bool ascending) {
    if (columnIndex == 0) {
      usersData.sort((user1, user2) =>
          compareString(ascending, user1.counselorName, user2.counselorName));
    } else if (columnIndex == 1) {
      usersData.sort((user1, user2) => compareString(ascending,
          '${user1.dateAndTimeOfCall}', '${user2.dateAndTimeOfCall}'));
    } else if (columnIndex == 2) {
      usersData.sort((user1, user2) =>
          compareString(ascending, user1.enquiryName, user2.enquiryName));
    } else if (columnIndex == 3) {
      usersData.sort((user1, user2) => compareString(
          ascending, '${user1.typeOfEnquiry}', '${user2.typeOfEnquiry}'));
    }

     // This causes the widget tree rebuild ? and consequent call to StreamBuilder ?
    setState(() {
      this.sortColumnIndex = columnIndex;
      this.isAscending = ascending;
    });
  }

我假设, onSort 可以完成工作,并且该表针对一个小实例进行了排序。然后 onSort 中的 setState 触发小部件树的重建,因此再次调用 StreamBuilder,它获取新数据并撤消排序,因为表重新显示来自 UserData 的数据。

编辑 现在我的解决方法是将 StreamBuilder 更改为 FutureBuilder(大数据,仅获取一次),然后为了避免由于小部件重建而再次调用 FireStore,我正在检查数据列表的长度。

builder: (context, snapshot) {
              if (snapshot.hasData) {
                if (usersData.length > 0) {
                 // if usersData already fetched - reload the DataTable  without making a fresh call to Publisher (FireStore)
                  return DataTable(
                    sortAscending: isAscending,
                    sortColumnIndex: sortColumnIndex,
                    columns: getColumns(columns),
                    rows: getRows(usersData),
                  );
                }

标签: fluttersortinggoogle-cloud-firestoredatatable

解决方案


推荐阅读