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

使用GetX从自定义API获取分类数据失败,请求排查问题

解决GetX获取API分类数据失败问题

问题分析

核心问题包括:

  • 控制器数据未用GetX响应式包装,视图无法监听更新
  • 视图未触发数据请求,也未监听加载状态与数据变化
  • 模型构造函数参数设置不合理,易引发解析异常
  • ListView缺少必要的数据源配置

修复步骤

1. 修正模型文件 Category.dart

将Data类默认构造函数参数改为可选,避免API字段缺失或解析时出错:

class Category {
  List<Data>? data;

  Category({this.data}); // 改为可选参数

  Category.fromJson(Map<String, dynamic> json) {
    if (json['data'] != null) {
      data = <Data>[];
      json['data'].forEach((v) {
        data!.add(Data.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    if (this.data != null) {
      data['data'] = this.data!.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Data {
  int? id;
  String? image;
  String? categoryName;
  String? categoryDes;
  int? activation;
  String? createdAt;
  String? updatedAt;

  // 所有参数改为可选
  Data({this.id, this.image, this.categoryName, this.categoryDes, this.activation, this.createdAt, this.updatedAt});

  Data.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    image = json['image'];
    categoryName = json['category_name'];
    categoryDes = json['category_des'];
    activation = json['activation'];
    createdAt = json['created_at'];
    updatedAt = json['updated_at'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['id'] = id;
    data['image'] = image;
    data['category_name'] = categoryName;
    data['category_des'] = categoryDes;
    data['activation'] = activation;
    data['created_at'] = createdAt;
    data['updated_at'] = updatedAt;
    return data;
  }
}

2. 修复控制器文件 CategoryController.dart

用GetX响应式变量存储数据,初始化时自动请求数据:

import 'dart:convert';
import 'package:get/get.dart';
import 'package:we_serve/models/Category.dart';
import 'package:http/http.dart' as http;

class CategoryController extends GetxController{
  final isLoading = false.obs;
  final _category = Rx<Category?>(null); // 响应式可空对象

  Category? get category => _category.value; // 暴露getter

  @override
  void onInit() {
    super.onInit();
    fetchData(); // 初始化自动请求数据
  }

  fetchData() async {
    try{
      isLoading(true);
      final response = await http.get(Uri.parse('http://127.0.0.1:8000/api/category'));
      if(response.statusCode == 200){
        final result = jsonDecode(response.body);
        _category.value = Category.fromJson(result); // 更新响应式变量
      }else{
        print("HTTP请求失败:状态码${response.statusCode}");
      }
    }catch(e){
      print("数据获取异常:$e");
    }finally{
      isLoading(false);
    }
  }
}

3. 更新视图文件 Category_slider.dart

用Obx监听状态变化,配置ListView并显示分类数据:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:we_serve/controllers/CategoryController.dart';
import '../models/Category.dart';

class CategorySlider extends StatelessWidget {
  final CategoryController categoryController = Get.put(CategoryController());
  
  @override
  Widget build(BuildContext context) {
    return Obx(() {
      if(categoryController.isLoading.value){
        return const Center(child: CircularProgressIndicator());
      }

      final categories = categoryController.category?.data ?? [];
      return ListView.builder(
        scrollDirection: Axis.horizontal,
        shrinkWrap: true,
        padding: const EdgeInsets.only(right: 8),
        itemCount: categories.length,
        itemBuilder: (BuildContext context, int index) {
          final category = categories[index];
          return Container(
            child: Center(
              child: Column(
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.all(10.0),
                    child: Container(
                      width: 200,
                      height: 120,
                      child: ElevatedButton(
                        style: ElevatedButton.styleFrom(
                            backgroundColor: Colors.white,
                            shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(20),
                                side: const BorderSide(color: Color(0xFF1818B4)))),
                        onPressed: () {},
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: <Widget>[
                            Text(
                              category.categoryName ?? "未命名分类",
                              style: const TextStyle(color: Colors.black),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          );
        },
      );
    });
  }
}

额外注意事项

  • 模拟器/真机网络适配:Android模拟器需将127.0.0.1替换为10.0.2.2,iOS模拟器可直接使用127.0.0.1
  • 网络权限配置:Android在AndroidManifest.xml添加<uses-permission android:name="android.permission.INTERNET"/>;iOS在Info.plist配置App Transport Security例外

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 19:58:13