如何使用 Flutter 数据模型和 Future Builder

Posted

技术标签:

【中文标题】如何使用 Flutter 数据模型和 Future Builder【英文标题】:How To Work with Flutter Data Model and Future Builder 【发布时间】:2021-06-17 10:30:41 【问题描述】:

我正在使用测试应用程序,它只显示来自 api 调用的员工列表,因为我已经为员工创建了数据模型并调用它。但我一无所获

这里是sn-ps

import 'package:flutter/material.dart';
import '../models/employee.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class EmployeeListScreen extends StatefulWidget 
  EmployeeListScreen(Key key) : super(key: key);

  @override
  _EmployeeListScreenState createState() => _EmployeeListScreenState();


class _EmployeeListScreenState extends State<EmployeeListScreen> 
  @override
  void initState() 
    super.initState();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
        appBar: AppBar(
          title: Text("Employee List"),
        ),
        body: FutureBuilder(
          future: fetchEmployees(),
          builder: (BuildContext context, AsyncSnapshot snapshot) 
            if (snapshot.connectionState == ConnectionState.none) 
              return Center(
                child: Text("None"),
              );
            
            if (snapshot.connectionState == ConnectionState.active) 
              return Center(
                child: CircularProgressIndicator(),
              );
            
            if (snapshot.connectionState == ConnectionState.done) 
              if (snapshot.data == null) 
                return Center(child: Text("No Employees"));
               else 
                return Center(
                  child: ListView.builder(
                    itemCount: snapshot.data.length[![enter image description here][1]][1],
                    itemBuilder: (BuildContext context, int index) 
                      return Text(snapshot.data[index]["name"]);
                    ,
                  ),
                );
              
            
            if (snapshot.connectionState == ConnectionState.waiting) 
              return Center(
                child: CircularProgressIndicator(),
              );
            

            return Container();
          ,
        ));
  

  Future<List<Employee>> fetchEmployees() async 
    final response = await http.get(
        "http://192.168.1.199/projects/ci/employee/api/getEmployees",
        headers: "accept": "application/json");
    debugPrint("Api Finished...");

    if (response.statusCode == 200) 
      final result = jsonDecode(response.body);
      Iterable list = result['employees'];
      print(list);
      return list.map((employee) => Employee.fromJson(employee)).toList();
     else 
      throw Exception("Failed to Load Employees");
    
  

查看屏幕截图。

我在使用传统的api调用而不使用模型和工厂方法时得到了结果,这让我很困惑,也建议我最好的网站来学习这些东西,即使我看到官方文档也完全不清楚。

【问题讨论】:

【参考方案1】:

为了帮助调试问题,试试下面这个简化的代码怎么样。从loadSlowData() 方法内部调用您的fetchEmployees()

(直接在FutureBuilder future: 中进行异步调用不是一个好习惯。相反,在StatefulWidgetinitState 中进行异步调用。因为FutureBuilderbuild() 方法内,而@987654329 @ 每秒最多可以调用 60 次,您显然可以看到问题。如果您碰巧在小部件树的那部分使用动画,以 60fps 刷新,您就会遇到这种情况。)

import 'package:flutter/material.dart';

class FutureBuilderStatefulPage extends StatefulWidget 
  @override
  _FutureBuilderStatefulPageState createState() => _FutureBuilderStatefulPageState();


class _FutureBuilderStatefulPageState extends State<FutureBuilderStatefulPage> 
  Future<String> _slowData;

  @override
  void initState() 
    super.initState();
    _slowData = loadSlowData();
  

  Future<String> loadSlowData() async 
    // replace with your async call ↓ ↓
    return await Future.delayed(Duration(seconds: 2), () => 'The Future has arrived');
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text('FutureBldr Stateful'),
      ),
      body: FutureBuilder<String>(
        future: _slowData,
        builder: (context, snapshot) 
          if (snapshot.hasData) 
            return Center(child: Text(snapshot.data));
          
          return Center(child: Text('Loading...'));
        ,
      ),
    );
  

【讨论】:

已经尝试过你的建议,但屏幕上没有任何反应,看看我未来的电话,Future> _fetchAllEmployees() async http.Response response = await http .get( "192.168.1.199/projects/ci/employee/api/getEmployees"); var responseBody = json.decode(response.body); var employees = responseBody['employees']; List allEmployees = new List(); for (var employee in employees) allEmployees.add(new Employee .fromJson(employee));//无法将这个添加到列表中,所以出现了null return allEmployees;

以上是关于如何使用 Flutter 数据模型和 Future Builder的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中基于 Future 结果构建 Stream?

如何将 Future<dynamic> 转换为 dart:flutter 中的字符串

Flutter - 如何在“Future”中显示“snackbar”

使用flutter_local_notifications时如何在Flutter中将Future<Null>转换为Future<dynamic>?

Flutter 通过查询 Firestore 创建自定义用户模型给出“类型‘Future<dynamic>’不是‘String’类型的子类型”错误

如何在 Flutter 中获取 Future<List> 项的某个数据索引?