flutter - 如何移动函数**FuturefetchData()** 到服务类
问题描述
我想将我的代码重组为MVVM,我是新手,如何将上面的函数重组为Service Class import 'dart:convert';
import 'package:amaizi_test/models/UserModel.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class JsonApiPhp extends StatefulWidget {
@override
_JsonApiPhpState createState() => _JsonApiPhpState();
}
class _JsonApiPhpState extends State<JsonApiPhp> {
bool loading = true;
final String url = 'https://jsonplaceholder.typicode.com/users';
var client = http.Client();
List<UserModel> users = [];
@override
void initState(){
fetchData();
super.initState();
}
我想重组我的文件,
Future<void> fetchData() async {
http.Response response = await client.get(Uri.parse(url));
if(response.statusCode == 200){ // Connection Ok
List responseJson = json.decode(response.body);
responseJson.map((m) => users.add(new UserModel.fromJson(m))).toList();
setState(() {
loading = false;
});
} else {
throw('error');
}
}
并在 HomePage InitState 中初始化
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
child: loading ?
Container(
child: Center(
child: CircularProgressIndicator(),
),
) :
ListView.builder(
itemCount: users.length,
itemBuilder: (BuildContext context, int index){
return Card(
child: ListTile(
title: Text(
users[index].name,
),
),
);
},
)
),
);
}
}
// 函数调用API并显示在UI中
解决方案
例如,您可以在 lib 目录中创建目录“services”,然后使用您的服务类在该目录中创建 dart 文件。例如:
class ServerApiService{
Future<List<User>> fetchData() async {
///your code, but without setState()
return users;
}
}
在 initState 之后,您可以创建服务对象并从服务类调用 fetchData 函数。但不是每次都创建服务类对象,我建议在 MaterialApp 之上创建服务对象,并在应用程序的任何小部件中使用 Provider 访问服务对象。
您可以使用 FutureBuilder 小部件从 fetchData() 方法访问数据。
FutureBuilder<List<User>>(
future: users,
builder: (context, snapshot) {
if (snapshot.hasData) {
var data = snapshot.data!;
return ListView.builder(
itemCount: data.length,
itemBuilder: (BuildContext context, int index) {
User user = data[index];
return Card(
child: ListTile(
title: Text(
user.name,
),
),
)
});
}
else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
else {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
}
});
访问 FutureBuilder(未来:用户)的用户从服务对象获取数据。
还有一点注意:如果在 initState() 内部,您将在其他代码上方调用 super.initState() 会更好。用 super.initState 开始你的 initState,用 super.dispose 结束你的 dispose
推荐阅读
- awk - Sed/Awk:如果重复第一行中的模式,如何查找和删除两行;重击
- android - 如何解决警告:未经检查的调用'addOnSuccessListener(OnSuccessListener )
- c# - 如何更改 FreshMvvm 期望实体的页面名称的方式?
- tensorflow - 如何保存网络的一部分?
- sql - 插入带有 WITH 子句的表在 postgres 中不起作用
- mysql - SQL:替代 COALESCE() 函数,将所有值分组到一列
- html - div-contaier 中带有滚动条的 CSS 网格
- sublimetext3 - 如何在 sublime text 3 中搜索带有特殊字符的特定文本?
- jquery - 使用 Angular 中的过滤器更新列表
- ios - 忘记了 Fastlane 匹配密码