You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Firestore集合属性映射到PlutoGrid的单元格中?

问题:Firestore数据映射到PlutoGrid单元格的最后一步问题

我需要将Firestore查询获取的值映射到PlutoGrid结构中对应列的对应单元格,目前已接近完成,但最后一步存在困难。

核心代码

class RowInfinityScrollScreen extends StatefulWidget {
  static const routeName = 'feature/row-infinity-scroll';

  const RowInfinityScrollScreen({Key? key}) : super(key: key);

  @override
  _RowInfinityScrollScreenState createState() =>
      _RowInfinityScrollScreenState();
}

class _RowInfinityScrollScreenState extends State<RowInfinityScrollScreen> {
  late List<PlutoColumn> columns;
  late List<PlutoRow> rows;
  late PlutoGridStateManager stateManager;
  late List<PlutoRow> dBRows;

  @override
  void initState() {
    super.initState();

    columns = [
      PlutoColumn(
        title: 'Restaurants',
        field: 'name',
        type: PlutoColumnType.text(),
      ),
      PlutoColumn(
        title: 'Stars',
        field: 'star',
        type: PlutoColumnType.number(),
      ),
    ];

    // 初始传入空行
    rows = [];

    // 从服务器获取数据
    dBRows = rowsByColumns(length: 100, columns: columns);    
  }

  static List<PlutoRow> rowsByColumns({
    required int length,
    required List<PlutoColumn> columns,
  }) {
    return List<int>.generate(length, (index) => index).map((_) {
      return rowByColumns(columns);
    }).toList();
  }

  static PlutoRow rowByColumns(List<PlutoColumn> columns) {
    return PlutoRow(cells: _cellsByColumn(columns));
  }

  static Map<String, PlutoCell> _cellsByColumn(List<PlutoColumn> columns) {
    final cells = <String, PlutoCell>{};
    for (var column in columns) {
      cells[column.field] = PlutoCell(
        value: DbService.withoutUID().getCollection(),
      );
    }
    return cells;
  }

getCollection方法

Future<List> getCollection() async {
  QuerySnapshot snapshot = await bookiesCollection.get();
  List<dynamic> result = snapshot.docs.map((doc) => doc.data()).toList();
  return result;
}

Firestore返回数据格式

{star: 4, name: Restaurant_0}
{star: 1, name: Restaurant_1}
{star: 5, name: Restaurant_2}

期望PlutoGrid呈现效果

Restaurant    |  Stars
--------------------
Restaurant_0  |  4
Restaurant_1  |  1
Restaurant_2  |  5

解决方案

核心问题:

  1. getCollection()是异步方法,直接赋值给PlutoCell的value会导致value是Future对象而非实际数据;
  2. 当前逻辑生成固定100行,但实际需要将Firestore返回的每条数据对应转换为一行PlutoRow。

修正步骤:

  1. 异步加载并转换数据
    修改initState,通过帧回调实现异步数据加载,将Firestore数据直接映射为PlutoRow:

    @override
    void initState() {
      super.initState();
    
      columns = [
        PlutoColumn(
          title: 'Restaurants',
          field: 'name',
          type: PlutoColumnType.text(),
        ),
        PlutoColumn(
          title: 'Stars',
          field: 'star',
          type: PlutoColumnType.number(),
        ),
      ];
    
      rows = [];
    
      // 异步加载Firestore数据并转换为PlutoRow
      WidgetsBinding.instance.addPostFrameCallback((_) async {
        List<dynamic> firestoreData = await DbService.withoutUID().getCollection();
        setState(() {
          rows = firestoreData.map((data) {
            return PlutoRow(cells: {
              'name': PlutoCell(value: data['name']),
              'star': PlutoCell(value: data['star']),
            });
          }).toList();
        });
      });
    }
    
  2. 移除无用静态方法
    原rowsByColumns、rowByColumns、_cellsByColumn方法不再需要,直接删除即可。

  3. 优化数据类型(可选)
    给getCollection指定明确返回类型,避免dynamic:

    Future<List<Map<String, dynamic>>> getCollection() async {
      QuerySnapshot snapshot = await bookiesCollection.get();
      return snapshot.docs.map((doc) => doc.data() as Map<String, dynamic>).toList();
    }
    
  4. 绑定PlutoGrid数据
    确保PlutoGrid组件使用更新后的rows数据:

    PlutoGrid(
      columns: columns,
      rows: rows,
      onLoaded: (PlutoGridOnLoadedEvent event) {
        stateManager = event.stateManager;
      },
    )
    

修改后,Firestore返回的每条数据会被正确映射到PlutoGrid的对应列和单元格,呈现预期效果。

内容的提问来源于stack exchange,提问作者Max

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 21:10:28