flutter - 如何重用模型作为父级
问题描述
我收到json
如下示例格式的回复
// call 1 : /all-users
{
"success": true,
"message": "All Users list",
"data": [{
"code": "USR001",
"name": "User One"
}]
}
// call 2 - /user-details/USR001
{
"success": true,
"message": "User Details of USR001",
"data": {
"code": "USR001",
"firstName": "User",
"lastName": "One",
"email": "userOne@email.com",
}
}
我的ApiResponse
模型是
class ApiResponse {
bool success;
String message;
List<Data> data;
ApiResponse({this.success, this.message, this.data});
ApiResponse.fromJson(Map<String, dynamic> json) {
success = json['success'];
message = json['message'];
if (json['data'] != null) {
data = new List<Data>();
json['data'].forEach((v) {
data.add(new Data.fromJson(v));
});
}
}
}
响应中的data
可能是对象或数组,取决于调用。我想通过将模型扩展为单独的模型来重用ApiResponse
两个调用的模型。data
但我不知道该怎么做。
解决方案
我认为最简单的方法是简单地拥有两个扩展类ApiResponse
,并且两者都可以调用你的 super.fromJson。由于数据会有所不同,您可以执行以下两项操作之一:
- 拉出
data
新的派生类,并在它们的构造函数中分别解析 - 变成
ApiResponse
一个具有泛型的类(ApiResponse<T>
,其中data
是 类型T
)。如果您采用这种方法,您还必须传递一个可以解析数据 json 的函数。
就个人而言,我认为为此使用泛型是过分的,但我想将其作为一种可能的解决方案来提及。考虑到这一点,您可以执行以下操作:
class ApiResponseBase {
bool success;
String message;
ApiResponse({this.success, this.message});
ApiResponse.fromJson(Map<String, dynamic> json) {
success = json['success'];
message = json['message'];
}
}
class ApiResponseArray extends ApiResponseBase {
List<Data> data;
ApiResponseArray.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
if (json['data'] != null) {
json['data'].forEach((v) {
data.add(new Data.fromJson(v));
});
}
}
}
class ApiResponseObject extends ApiResponseBase {
Data data;
ApiResponseObject.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
if (json['data'] != null) {
data = new Data.fromJson(json['data']);
}
}
}
请注意我是如何从 中删除数据的,ApiResponseBase
因为它现在正在派生类中进行解析。
如果你真的不喜欢现在有两种数据定义的事实,你可以使用泛型而不需要增加复杂性:
class ApiResponseBase<T> {
bool success;
String message;
T data;
// same as before
}
class ApiResponseArray extends ApiResponseBase<List<Data>> {
// same as before
}
class ApiResponseObject extends ApiResponseBase<Data> {
// same as before
}
但无论哪种方式都有效。
推荐阅读
- visual-studio-code - VisualStudioCode 在调试时打印到终端时引发错误
- blockchain - 坚固性 v0.6.0。后备功能。他们需要什么?
- angular - httpClient 上的 Angular 循环
- yocto - gprolog 配方的 Autoreconf 失败
- ios - iOS推送通知,可以决定不触发通知吗?
- google-chrome - Chrome ffmpeg.js 无法制作超过 33 秒的视频
- python - 由用户介绍的坐标创建的关闭区域
- reactjs - 如何在 React 中更改数组状态的特定项目?
- node.js - 可以通过 VSCode 启动 Angular
- html - 如何使 div 中的链接在另一个 div 下可点击,但不更改 div 宽度?