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

如何从返回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自带的控制器来管理行数据,确保组件能正确响应数据变化:

  1. 添加PlutoGridController实例;
  2. 在获取数据后调用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 05:43:08