0

0

从 PHP API 获取数据并填充 Flutter 表格

DDD

DDD

发布时间:2025-10-18 09:05:00

|

949人浏览过

|

来源于php中文网

原创

从 php api 获取数据并填充 flutter 表格

本文档旨在指导开发者如何从 PHP API 获取数据,并使用 Flutter 的 Table 组件将数据动态地填充到表格中。文章将涵盖数据模型的定义、API 数据的获取、JSON 解析以及表格的构建,同时提供代码示例和注意事项,帮助开发者解决常见的 NoSuchMethodError 问题。

数据模型定义

首先,我们需要定义一个 Dart 类来映射从 PHP API 获取的 JSON 数据。根据提供的 JSON 示例,我们已经有了 Model 和 Tender 类。确保这些类中的字段类型与 API 返回的数据类型一致。例如,如果 API 返回的某个字段可能为 null,则在 Dart 类中将其声明为可空类型(例如 String? 或 dynamic)。

class Model {
  Model({
    this.id,
    this.goodsRef,
    this.loyer,
    this.bnCode,
    this.loyeeNo,
    this.contactName,
    this.contactTel,
    this.bnDesc,
    this.reqStatus,
    this.eMail,
    this.comments,
    this.tender,
    this.reqDate,
    this.sscOffice,
  });

  final String? id;
  final int? goodsRef;
  final String? loyer;
  final String? bnCode;
  final int? loyeeNo;
  final dynamic contactName;
  final dynamic contactTel;
  final String? bnDesc;
  final String? reqStatus;
  final dynamic eMail;
  final String? comments;
  final List? tender;
  final DateTime? reqDate;
  final dynamic sscOffice;

  factory Model.fromJson(Map json) => Model(
    id: json["\u0024id"] == null ? null : json["\u0024id"],
    goodsRef: json["goods_ref"] == null ? null : json["goods_ref"],
    loyer: json["loyer"] == null ? null : json["loyer"],
    bnCode: json["bn_code"] == null ? null : json["bn_code"],
    loyeeNo: json["loyee_no"] == null ? null : json["loyee_no"],
    contactName: json["contact_name"],
    contactTel: json["contact_tel"],
    bnDesc: json["bn_desc"] == null ? null : json["bn_desc"],
    reqStatus: json["req_status"] == null ? null : json["req_status"],
    eMail: json["e_mail"],
    comments: json["comments"] == null ? null : json["comments"],
    tender: json["tender"] == null ? null : List.from(json["tender"].map((x) => Tender.fromJson(x))),
    reqDate: json["req_date"] == null ? null : DateTime.tryParse(json["req_date"]),
    sscOffice: json["ssc_office"],
  );

  Map toJson() => {
    "\u0024id": id == null ? null : id,
    "goods_ref": goodsRef == null ? null : goodsRef,
    "loyer": loyer == null ? null : loyer,
    "bn_code": bnCode == null ? null : bnCode,
    "loyee_no": loyeeNo == null ? null : loyeeNo,
    "contact_name": contactName,
    "contact_tel": contactTel,
    "bn_desc": bnDesc == null ? null : bnDesc,
    "req_status": reqStatus == null ? null : reqStatus,
    "e_mail": eMail,
    "comments": comments == null ? null : comments,
    "tender": tender == null ? null : List.from(tender!.map((x) => x.toJson())),
    "req_date": reqDate == null ? null : reqDate!.toIso8601String(),
    "ssc_office": sscOffice,
  };
}

class Tender {
  Tender({
    this.id,
    this.goodsRef,
    this.inNo,
    this.tenderNo,
    this.closingDate,
  });

  final String? id;
  final int? goodsRef;
  final int? inNo;
  final String? tenderNo;
  final String? closingDate;

  factory Tender.fromJson(Map json) => Tender(
    id: json["\u0024id"] == null ? null : json["\u0024id"],
    goodsRef: json["goods_ref"] == null ? null : json["goods_ref"],
    inNo: json["in_no"] == null ? null : json["in_no"],
    tenderNo: json["tender_no"] == null ? null : json["tender_no"],
    closingDate: json["closing_date"] == null ? null : json["closing_date"],
  );

  Map toJson() => {
    "\u0024id": id == null ? null : id,
    "goods_ref": goodsRef == null ? null : goodsRef,
    "in_no": inNo == null ? null : inNo,
    "tender_no": tenderNo == null ? null : tenderNo,
    "closing_date": closingDate == null ? null : closingDate,
  };
}

注意:

  • 将可能为 null 的字段类型改为可空类型,例如 String?。
  • 使用 DateTime.tryParse 来解析日期字符串,避免解析失败。
  • 在 toJson 方法中,对可空列表进行非空判断。

从 PHP API 获取数据

使用 http 包从 PHP API 获取数据。确保已在 pubspec.yaml 文件中添加了 http 依赖。

立即学习PHP免费学习笔记(深入)”;

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.5 # 确保使用最新版本

然后,可以使用以下代码从 API 获取数据:

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

Future> fetchItems(String email) async {
  String apiurl = "YOUR_API_ENDPOINT"; // 替换为你的 API 端点
  var response = await http.post(Uri.parse(apiurl), body: {
    'username': email //get the username text
  });

  if (response.statusCode == 200) {
    // 使用 utf8.decode 处理中文乱码问题
    final decodedBody = utf8.decode(response.bodyBytes);
    List jsonResponse = jsonDecode(decodedBody);
    List model = jsonResponse.map((item) => Model.fromJson(item)).toList();
    return model;
  } else {
    throw Exception('Failed to load data from API');
  }
}

注意:

  • 将 YOUR_API_ENDPOINT 替换为你的实际 API 端点。
  • 使用 utf8.decode(response.bodyBytes) 处理中文乱码问题。
  • 使用 Model.fromJson(item) 将 JSON 数据转换为 Model 对象。
  • 添加错误处理,当 API 请求失败时抛出异常。

构建 Flutter 表格

获取到数据后,就可以使用 Table 组件来显示数据。

Soofy
Soofy

通过AI聊天学习新语言

下载
import 'package:flutter/material.dart';

class MyTable extends StatefulWidget {
  final String email;

  const MyTable({Key? key, required this.email}) : super(key: key);

  @override
  _MyTableState createState() => _MyTableState();
}

class _MyTableState extends State {
  late Future> _dataFuture;

  @override
  void initState() {
    super.initState();
    _dataFuture = fetchItems(widget.email);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Data Table')),
      body: FutureBuilder>(
        future: _dataFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          } else if (snapshot.hasError) {
            return Center(child: Text('Error: ${snapshot.error}'));
          } else if (snapshot.hasData) {
            return SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              child: Table(
                border: TableBorder.all(width: 1, color: Colors.black45),
                columnWidths: const {
                  0: IntrinsicColumnWidth(),
                  1: IntrinsicColumnWidth(),
                  2: IntrinsicColumnWidth(),
                  3: IntrinsicColumnWidth(),
                },
                children: [
                  // 表头
                  TableRow(
                    children: [
                      TableCell(child: Center(child: Padding(padding: const EdgeInsets.all(8.0), child: const Text('Goods Ref')))),
                      TableCell(child: Center(child: Padding(padding: const EdgeInsets.all(8.0), child: const Text('Loyer')))),
                      TableCell(child: Center(child: Padding(padding: const EdgeInsets.all(8.0), child: const Text('BN Code')))),
                      TableCell(child: Center(child: Padding(padding: const EdgeInsets.all(8.0), child: const Text('BN Desc')))),
                    ],
                  ),
                  // 表格数据
                  ...snapshot.data!.map((item) {
                    return TableRow(
                      children: [
                        TableCell(child: Center(child: Padding(padding: const EdgeInsets.all(8.0), child: Text(item.goodsRef?.toString() ?? '')))),
                        TableCell(child: Center(child: Padding(padding: const EdgeInsets.all(8.0), child: Text(item.loyer ?? '')))),
                        TableCell(child: Center(child: Padding(padding: const EdgeInsets.all(8.0), child: Text(item.bnCode ?? '')))),
                        TableCell(child: Center(child: Padding(padding: const EdgeInsets.all(8.0), child: Text(item.bnDesc ?? '')))),
                      ],
                    );
                  }).toList(),
                ],
              ),
            );
          } else {
            return const Center(child: Text('No data available'));
          }
        },
      ),
    );
  }
}

关键点:

  • 使用 FutureBuilder 来处理异步数据加载。
  • 在 Text 组件中使用 item.propertyName ?? '' 来处理可能为 null 的值,避免 NoSuchMethodError。
  • 使用 SingleChildScrollView 包裹 Table 组件,以支持水平滚动。
  • 添加表头,使表格更易于理解。
  • 使用 IntrinsicColumnWidth 可以让单元格根据内容自动调整宽度。

解决 NoSuchMethodError

NoSuchMethodError: The getter 'length' was called on null 错误通常发生在尝试访问 null 值的属性时。例如,如果 nameone.sn 为 null,则 nameone.sn.length 会抛出此错误。

解决方法是在访问可能为 null 的属性之前,使用空值检查或空值合并运算符 ??。例如:

Text(nameone.sn ?? "") // 如果 nameone.sn 为 null,则显示空字符串

或者,可以使用条件判断:

Text(nameone.sn != null ? nameone.sn : "")

在上面的代码示例中,我们已经使用了空值合并运算符 ?? 来处理可能为 null 的值,从而避免了 NoSuchMethodError。

总结

本文档详细介绍了如何从 PHP API 获取数据并在 Flutter 中使用 Table 组件显示数据。通过定义数据模型、使用 http 包获取数据、解析 JSON 数据以及使用空值合并运算符处理 null 值,可以有效地构建动态表格并避免常见的错误。记住,在处理 API 数据时,始终要考虑数据可能为 null 的情况,并采取相应的措施来避免运行时错误。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

1801

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1204

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1099

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

948

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1396

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1228

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1439

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1303

2023.11.13

ip地址修改教程大全
ip地址修改教程大全

本专题整合了ip地址修改教程大全,阅读下面的文章自行寻找合适的解决教程。

81

2025.12.26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 6.9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号