如何从返回JSON的API动态加载PlutoGrid数据?问题求助
问题
动态加载数据到PlutoGrid时无行数据显示,无任何错误提示。已确认API返回的JSON可转为字符串列表并映射为PlutoRow对象,静态填充该列表时PlutoGrid能正常显示数据。调试过程:
- Widget的
build()先执行,此时rowsProviders为空; initState()随后执行,成功填充rowsProviders;build()再次执行,rowsProviders已有数据并赋值给PlutoGrid的rows属性,但网格仅显示列标题,无行数据。
原代码:
import 'dart:convert'; import 'package:http/http.dart' as http; import "package:flutter/material.dart"; import 'package:pluto_grid/pluto_grid.dart'; const String API_URL_LLMT_PROVIDER_ROUTE = "http://127.0.0.1:5000/get_mt_providers"; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp ( title: 'LL Translate', theme: ThemeData(primarySwatch: Colors.blue,), home: const DetectorPage(title: 'LLTS MT Tools'), debugShowCheckedModeBanner: true, ); } } class DetectorPage extends StatefulWidget { const DetectorPage({Key? key, required this.title}) : super(key: key); final String title; @override State<DetectorPage> createState() => _DetectorPageState(); } class _DetectorPageState extends State<DetectorPage> { final List<PlutoColumn> columnsProviders = []; List<PlutoRow> rowsProviders = []; List<String> providers = []; @override void initState() { super.initState(); columnsProviders.addAll ( [ PlutoColumn ( width: 400, backgroundColor: Colors.blue, title: 'MT Provider', field: 'MT Provider Tested', type: PlutoColumnType.text(), enableRowChecked: true, ), PlutoColumn ( width: 95, backgroundColor: Colors.blue, title: 'WER', field: 'Leven', type: PlutoColumnType.text(), enableFilterMenuItem: true, textAlign: PlutoColumnTextAlign.center, titleTextAlign: PlutoColumnTextAlign.center, ), PlutoColumn ( width: 100, backgroundColor: Colors.blue, title: 'BLEU', field: 'BLEU', type: PlutoColumnType.text(), enableFilterMenuItem: false, textAlign: PlutoColumnTextAlign.center, titleTextAlign: PlutoColumnTextAlign.center, ), PlutoColumn ( width: 120, backgroundColor: Colors.blue, title: 'Combined', field: 'Combined', type: PlutoColumnType.text(), enableFilterMenuItem: false, textAlign: PlutoColumnTextAlign.center, titleTextAlign: PlutoColumnTextAlign.center, ), ] ); loadMtProviders(); } void loadMtProviders() async { providers = await getMtProviders(); rowsProviders = providers.map((item) { return PlutoRow ( cells: { 'MT Provider Tested': PlutoCell(value: item), 'Leven': PlutoCell(value: ''), 'BLEU': PlutoCell(value: ''), 'Combined': PlutoCell(value: ''), }, ); }).toList(); setState(() { }); } Future<List<String>> getMtProviders() async { var url = Uri.parse(API_URL_LLMT_PROVIDER_ROUTE); var response = await http.get(url); if (response.statusCode == 200) { var value = response.body; var jsonResponse = jsonDecode(value); List<String> result = jsonResponse.cast<String>(); return result; } else { print('Request failed with status: ${response.statusCode}.'); return ['0']; } } @override Widget build(BuildContext context) { return Scaffold ( body: SizedBox ( child: PlutoGrid ( columns: columnsProviders, rows: rowsProviders, ), ) ); } }
解决方案
问题核心是Flutter状态检测未感知到rowsProviders的变化,或PlutoGrid未正确响应列表更新。以下是两种修复方式:
方式一:通过PlutoGridController更新(推荐)
使用PlutoGrid自带的控制器来管理行数据,确保组件能正确响应数据变化:
- 添加
PlutoGridController实例; - 在获取数据后调用
controller.setRows()更新行数据。
修改后的关键代码:
class _DetectorPageState extends State<DetectorPage> { final List<PlutoColumn> columnsProviders = []; List<PlutoRow> rowsProviders = []; List<String> providers = []; final PlutoGridController _controller = PlutoGridController(); // 添加控制器 // ... 其他代码不变 void loadMtProviders() async { providers = await getMtProviders(); final newRows = providers.map((item) { return PlutoRow ( cells: { 'MT Provider Tested': PlutoCell(value: item), 'Leven': PlutoCell(value: ''), 'BLEU': PlutoCell(value: ''), 'Combined': PlutoCell(value: ''), }, ); }).toList(); _controller.setRows(newRows); // 通过控制器更新行数据 } @override Widget build(BuildContext context) { return Scaffold ( body: SizedBox ( child: PlutoGrid ( columns: columnsProviders, rows: rowsProviders, controller: _controller, // 绑定控制器 ), ) ); } }
方式二:强制更新列表引用
在setState()内部重新创建列表引用,让Flutter明确感知到数据变化:
修改loadMtProviders中的setState部分:
void loadMtProviders() async { providers = await getMtProviders(); final newRows = providers.map((item) { return PlutoRow ( cells: { 'MT Provider Tested': PlutoCell(value: item), 'Leven': PlutoCell(value: ''), 'BLEU': PlutoCell(value: ''), 'Combined': PlutoCell(value: ''), }, ); }).toList(); setState(() { rowsProviders = List.from(newRows); // 创建新列表引用 }); }
两种方式都能解决问题,方式一更符合PlutoGrid的设计规范,推荐使用。
内容的提问来源于stack exchange,提问作者Steve3p0
相关产品推荐
相关产品推荐

