Flutter数据上下文管理插件datacontext的使用
Flutter数据上下文管理插件datacontext的使用
DataContext 是一个库,它允许你将服务器API映射到你的应用中,并创建一个包含所有数据的数据上下文。它封装了一个 HttpClient
,用于发送和获取数据。此外,它还允许你为数据集添加关系,以便你可以轻松地在DataContext中导航。另外,结合 provider
包,你可以将DataContext添加到你的小部件树中,以便从应用的任何地方访问数据。
一些出色的功能可能包括:
- 数据保存在内存中,你可以控制它们。
- 你可以以多种方式跟踪IO过程。
- 你可以使用特定的小部件来避免向用户显示损坏的数据。
使用方法
要设置你的应用并使用此包的所有功能,请遵循以下步骤(在将其添加到你的 pubspec.yaml
文件之后):
- 构建数据模型
- 构建数据上下文
- 使用它!
观察:为了说明此包的功能,我们将构建一个简单的应用,该应用显示餐厅及其提供的食物。数据将从一个假设的API获取。
构建数据模型
首先,你的数据模型需要扩展由我们的包提供的抽象类 DataClass
。这意味着你的类具有解析和(反)序列化过程的方法和构造函数。但是别担心,你不需要徒手做这些。检查这个扩展程序,它可以为你创建大部分方法。因此,你可以安装它,创建你的类,扩展 DataClass
并基于此扩展创建方法。
class Food extends DataClass {
String? id;
String? name;
double? price;
Food({this.id, this.name, this.price});
[@override](/user/override)
Map<String, dynamic> toMap() => {'id': id, 'name': name, 'price': price};
[@override](/user/override)
Food fromMap(Map<String, dynamic> map) => Food.fromMap(map);
[@override](/user/override)
String toJson() => json.encode(toMap());
factory Food.fromMap(Map<String, dynamic> map) =>
Food(id: map['id'], name: map['name'], price: map['price']);
factory Food.fromJson(String source) => Food.fromMap(json.decode(source));
}
class Restaurant extends DataClass {
String? id;
String? name;
Restaurant({this.id, this.name});
[@override](/user/override)
Map<String, dynamic> toMap() => {'id': id, 'name': name};
[@override](/user/override)
Restaurant fromMap(Map<String, dynamic> map) => Restaurant.fromMap(map);
[@override](/user/override)
String toJson() => json.encode(toMap());
factory Restaurant.fromMap(Map<String, dynamic> map) =>
Restaurant(id: map['id'], name: map['name']);
factory Restaurant.fromJson(String source) =>
Restaurant.fromMap(json.decode(source));
}
构建数据上下文
在这个步骤中,创建一个继承自 DataContext
的类。你需要重写 String origin
属性,设置API的基本URL,并重写 onSending
和 onReceiving
方法,这两个方法分别在每次请求之前和之后被调用。
同时,在这里你将声明你的数据上下文属性。对于每个你要从API消费的端点或模型,创建一个带有模型参数类型的 DataSet
对象。如果端点有一个子路径或类似 'path/:parentId/path2/:childId'
的URL,你可以使用 .addChild()
方法添加子路径,这是一个流式接口。
import 'package:data_context/data_context.dart';
class MyContext extends DataContext {
MyContext() : super('https://localhost/api');
[@override](/user/override)
void onReceiveData(Response response) {
print('RESULT: ${response.statusCode} - REQUEST: ${response.request!.url.toString()}');
}
[@override](/user/override)
void onSendData(APIRequest request) {
print(request.headers['Authorization']);
}
DataSet<Restaurant> restaurants = DataSet<Restaurant>(
route: '/restaurants',
idFieldGetter: (r) => r.id,
instanceBuilder: () => Restaurant())
.withChild(DataSet<Food>(
route: '/restaurants/:parentId/foods',
idFieldGetter: (f) => f.id,
instanceBuilder: () => Food()));
}
使用它!
构建好你的DataContext后,你可以通过从任何地方访问它的实例来使用它。Dart允许你以多种方式做到这一点。在这种情况下,我们使用的是 ChangeNotifierProvider
小部件,它是来自 package:provider/provider.dart
包的一部分,这样我们可以将其添加到我们的小部件树的顶部,并通过 Provider.of(context)
功能恢复它。现在,要从API获取数据,只需调用 context.restaurants.get()
即可。
import 'package:datacontext/datacontext.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
ChangeNotifierProvider(create: (context) => MyContext(), child: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final DataSet<Restaurant> restaurants = DataSet.of<Restaurant>();
[@override](/user/override)
void initState() {
super.initState();
restaurants.get();
}
void loadFoods(String restaurantId) {
restaurants.child<Food>(parentId: restaurantId).get();
}
[@override](/user/override)
Widget build(BuildContext context) {
return LoadStatusWidget(
status: restaurants.loadStatus,
loadWidget: (context) {
return ListView(
children: restaurants.list.map((restaurant) {
return TextButton(
child: Text(restaurant.name ?? 'No name'),
onPressed: () => loadFoods(restaurant.id ?? ''));
}).toList(),
);
},
);
}
}
更多关于Flutter数据上下文管理插件datacontext的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html