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

Flutter如何展示Node.js返回的API数据并实现列表项点击跳转

问题根因

你代码中核心错误是JSON反序列化逻辑不符合数据结构:

  • 服务端返回的response.body本身就是合法的对象数组JSON字符串,你额外拼接[]会将数据转为嵌套数组[[{...},{...}]],遍历的时候只会拿到外层数组的第一个元素(也就是完整的科目数组),所以只能展示第一条数据
  • 没有调用jsonDecode对JSON字符串做反序列化,直接强制类型转换会触发类型不匹配报错

解决方案

1. 修正fetchSubject请求方法

import 'dart:convert';
Future<List<Subject>> fetchSubject() async {
  var prefs = await SharedPreferences.getInstance();
  var token = prefs.getString('token');
  final response = await http.get(
      Uri.parse('http://localhost:8000/subjects'),
      headers: {'x-access-token': token!});
  // 先判断请求成功再解析
  if (response.statusCode == 200) {
    // 直接反序列化响应字符串,不需要额外拼接[]
    List<dynamic> list = jsonDecode(response.body);
    List<Subject> subjectList = list.map((item) => Subject.fromJson(item)).toList();
    return subjectList;
  } else {
    throw Exception('请求科目数据失败');
  }
}

2. 修正Subject模型类

将parseJson改为静态方法方便调用,删除冗余逻辑:

import 'dart:convert';
class Subject {
  final String name;

  Subject({
    required this.name,
  });

  factory Subject.fromJson(Map<String, dynamic> json) {
    return Subject(name: json['NAME'] as String);
  }

  // 改为静态方法,外部可直接调用
  static List<Subject> parseJson(String responseBody) {
    final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
    return parsed.map<Subject>((json) => Subject.fromJson(json)).toList();
  }
}

3. 界面列表展示+点击跳转实现

在你的State类中按以下逻辑编写FutureBuilder:

late Future<List<Subject>> futureSubject;

@override
void initState() {
  super.initState();
  futureSubject = fetchSubject();
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: const Text('科目列表')),
    body: FutureBuilder<List<Subject>>(
      future: futureSubject,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          // 用ListView展示所有科目
          return ListView.builder(
            itemCount: snapshot.data!.length,
            itemBuilder: (context, index) {
              Subject subject = snapshot.data![index];
              return ListTile(
                title: Text(subject.name),
                // 点击跳转逻辑,替换为你对应的目标页面
                onTap: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => YourTargetPage(subject: subject),
                    ),
                  );
                },
              );
            },
          );
        } else if (snapshot.hasError) {
          return Center(child: Text('加载失败: ${snapshot.error}'));
        }
        return const Center(child: CircularProgressIndicator());
      },
    ),
  );
}

你只需要将上述代码中的YourTargetPage替换为你实际要跳转的页面组件,即可实现点击科目跳转到对应页面的需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:24:01