0

在Raywenderlich的优秀 Flutter书中第 13 章致力于使用库ChopperJsonConverter从 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 通用的最佳方法是什么?提前谢谢。

4

1 回答 1

-1

这篇文章中解决

model_converter.dart

. . .
typedef CreateModelFromJson = dynamic Function(Map<String, dynamic> json);

class ModelConverter<Model> implements Converter {
  final CreateModelFromJson fromJson;

  ModelConverter({@required this.fromJson});
. . .
  final query = fromJson(mapData) as Model;
. . .

和 recipe_service.dart

. . .
      converter: ModelConverter<APIRecipeQuery>(
        fromJson: (json) => APIRecipeQuery.fromJson(json),
      ),
. . .
于 2021-04-09T09:03:32.220 回答