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

如何从API获取数组数据并映射到Dart对象?代码修复指导

修复方案

1. 修正JSON数据格式(后端返回需保证合法)

你的示例JSON存在语法错误,每个键值对末尾需加逗号,字符串值要包裹引号:

[
    {
        "channelId": 1,
        "channelTitle": "Photos",
        "channelImage": "pr01.jpg",
        "channelLastPost": null,
        "lastUpdate": null,
        "userRef": 1
    },
    {
        "channelId": 2,
        "channelTitle": "Science",
        "channelImage": "pr02.jpg",
        "channelLastPost": "For test ....",
        "lastUpdate": "2023-01-03",
        "userRef": 1
    }
]

2. 修复ChannelListModel.dart

  • 修正类型不匹配问题:userRef是数字类型,需转为String;lastPost、lastUpdate可能为null,需设为可空类型
  • 处理null值避免转换错误
class ChannelListModel {
  String creator;
  String? image;
  String title;
  String? lastPost;
  String? lastUpdate;

  ChannelListModel({
    required this.creator,
    this.image,
    required this.title,
    this.lastPost,
    this.lastUpdate,
  });

  factory ChannelListModel.fromJson(Map<String, dynamic> json) {
    return ChannelListModel(
      creator: json['userRef'].toString(),
      image: json['channelImage'],
      title: json['channelTitle'],
      lastPost: json['channelLastPost'],
      lastUpdate: json['lastUpdate'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      "userRef": int.tryParse(creator),
      "channelImage": image,
      "channelTitle": title,
      "channelLastPost": lastPost,
      "lastUpdate": lastUpdate
    };
  }
}

3. 修复HttpRequest.dart

List<ChannelListModel>.fromJson是错误用法,List类没有该方法,需遍历JSON数组逐个转换为Model对象:

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'ChannelListModel.dart';
import 'base.dart';

class HttpServices {
  Future<List<ChannelListModel>> getChannelList() async {
    var url = base.BaseURL.channelListUrl;
    final response = await http.get(Uri.parse(url));
    
    if (response.statusCode == 200) {
      List<dynamic> jsonList = jsonDecode(response.body);
      return jsonList.map((json) => ChannelListModel.fromJson(json)).toList();
    } else {
      throw Exception('Failed to load channel list');
    }
  }
}

4. 修复ChannelPage.dart

  • initState不能直接赋值异步方法结果,需用setState更新状态
  • 添加加载状态和错误处理,提升用户体验
import 'package:flutter/material.dart';
import 'HttpServices.dart';
import 'ChannelListModel.dart';
import 'ChannelCard.dart';

class Channels extends StatefulWidget {
  const Channels({super.key});

  @override
  State<Channels> createState() => _ChannelsState();
}

class _ChannelsState extends State<Channels> {
  List<ChannelListModel> channels = [];
  bool isLoading = true;

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

  Future<void> getChannelsFromHttp() async {
    try {
      var httpService = HttpServices();
      var result = await httpService.getChannelList();
      setState(() {
        channels = result;
        isLoading = false;
      });
    } catch (e) {
      setState(() {
        isLoading = false;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('加载失败:$e')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: isLoading 
          ? const Center(child: CircularProgressIndicator())
          : channels.isEmpty 
              ? const Center(child: Text('暂无频道数据'))
              : ListView.builder(
                  itemCount: channels.length,
                  itemBuilder: (context, index) => ChannelCard(channelModel: channels[index]),
                ),
    );
  }
}

代码拆分说明

保持现有文件拆分逻辑即可:

  • ChannelListModel.dart:仅存放数据模型类
  • HttpRequest.dart:仅封装网络请求逻辑
  • ChannelPage.dart:负责页面UI渲染与状态管理
  • ChannelCard.dart:单独实现列表项Widget(需确保该文件存在)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 22:55:32