在Raywenderlich的优秀 Flutter书中,第 13 章致力于使用库Chopper和JsonConverter从 api 获取响应。
Github 中的代码在这里
他还建议使用像函数式编程这样的响应包装器,类型为 Success/Error。
从响应到成功/错误包装器的 ModelConverter,适用于 APIRecipeQuery 模型,并且仅在一行中使用一种方法final recipeQuery = APIRecipeQuery.fromJson(mapData);
。进行泛型转换似乎很合乎逻辑,因为它是一个非常有用的类。
import 'dart:convert';
import 'package:chopper/chopper.dart';
import 'model_response.dart';
import 'recipe_model.dart';
class ModelConverter implements Converter {
@override
Request convertRequest(Request request) {
// Add a header to the request that says you have a request type of application/json using jsonHeaders.
// These constants are part of Chopper.
final req = applyHeader(
request,
contentTypeKey,
jsonHeaders,
override: false,
);
return encodeJson(req);
}
@override
Response<BodyType> convertResponse<BodyType, InnerType>(Response response) {
return decodeJson<BodyType, InnerType>(response);
}
Request encodeJson(Request request) {
final contentType = request.headers[contentTypeKey];
// Confirm contentType is of type application/json.
if (contentType != null && contentType.contains(jsonHeaders)) {
return request.copyWith(body: json.encode(request.body));
}
return request;
}
Response decodeJson<BodyType, InnerType>(Response response) {
final contentType = response.headers[contentTypeKey];
var body = response.body;
if (contentType != null && contentType.contains(jsonHeaders)) {
body = utf8.decode(response.bodyBytes);
}
try {
final mapData = json.decode(body);
if (mapData['status'] != null) {
return response.copyWith<BodyType>(
body: Error(Exception(mapData['status'])) as BodyType);
}
/*
The only line is next
*/
final recipeQuery = APIRecipeQuery.fromJson(mapData);
return response.copyWith<BodyType>(
body: Success(recipeQuery) as BodyType);
} catch (e) {
chopperLogger.warning(e);
return response.copyWith<BodyType>(body: Error(e) as BodyType);
}
}
因此,我尝试通过在构造函数中将模型作为参数传递:
class ModelConverter <T extends JsonConverter> implements Converter {
final T model;
ModelConverter ({@required this.model});
recipe_service.dart
我用调用它converter: ModelConverter(model: APIRecipeQuery)
,但我不知道如何静态引用模型,也无法访问该方法model.fromJson
接下来,我尝试只传递函数转换器:
class ModelConverter implements Converter {
Function fromJson;
ModelConverter ({@ required this.fromJson});
在 API 中使用 getter,并recipe_service.dart
使用converter: ModelConverter(fromJson: APIRecipeQuery.fjConverter)
class APIRecipeQuery {
static Function get fjConverter => _ $ APIRecipeQueryFromJson;
但我无法让它工作。
使 ModelConverter 通用的最佳方法是什么?提前谢谢。