如何将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
解决方案
核心问题:
getCollection()是异步方法,直接赋值给PlutoCell的value会导致value是Future对象而非实际数据;- 当前逻辑生成固定100行,但实际需要将Firestore返回的每条数据对应转换为一行PlutoRow。
修正步骤:
异步加载并转换数据
修改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(); }); }); }移除无用静态方法
原rowsByColumns、rowByColumns、_cellsByColumn方法不再需要,直接删除即可。优化数据类型(可选)
给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(); }绑定PlutoGrid数据
确保PlutoGrid组件使用更新后的rows数据:PlutoGrid( columns: columns, rows: rows, onLoaded: (PlutoGridOnLoadedEvent event) { stateManager = event.stateManager; }, )
修改后,Firestore返回的每条数据会被正确映射到PlutoGrid的对应列和单元格,呈现预期效果。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

