【问题标题】:Freezed - creating subclasses冻结 - 创建子类
【发布时间】:2020-12-02 14:09:54
【问题描述】:

我有一个来自 API 的 JSON 数据结构,其中包含一些字段。

我想创建一个 Freezed 模型,它有一个工厂来创建正确的子类,具体取决于其中一个字段的类型。

这是我的代码:

abstract class ItineraryData<T> implements _$ItineraryData<T> {
  const ItineraryData._();

  const factory ItineraryData({
    List<dynamic> summary,
    double totalPrice,
    double totalSeparatePay,
    double totalTax,
    List<String> covidAlerts,
  }) = _ItineraryData;

  const factory ItineraryData.flight({
    List<FlightSummary> summary,
    double totalPrice,
    double totalSeparatePay,
    double totalTax,
    List<String> covidAlerts,
  }) = _FlightItineraryData;

  const factory ItineraryData.hotel({
    List<HotelSummary> summary,
    double totalPrice,
    double totalSeparatePay,
    double totalTax,
  }) = _HotelItineraryData;

  const factory ItineraryData.car({
    List<CarSummary> summary,
    double totalPrice,
    double totalSeparatePay,
    double totalTax,
    List<String> covidAlerts,
  }) = _CarItineraryData;

  factory ItineraryData.fromJson(Map json) => _$ItineraryDataFromJson(json);
}

在这种情况下,访问ItineraryData&lt;A&gt; 的引用永远不会有summary 列表字段(应该始终存在,但类型不同)。

然后我尝试将未命名的构造函数更改为在 List 类型中使用&lt;T&gt;

const factory ItineraryData({
    List<T> summary,
    double totalPrice,
    double totalSeparatePay,
    double totalTax,
    List<String> covidAlerts,
}) = _ItineraryData;

然后我收到以下错误:

Could not generate `fromJson` code for `summary` because of type `T` (type parameter).
None of the provided `TypeHelper` instances support the defined type.
To support type paramaters (generic types) you can:
1) Use `JsonConverter`
  https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonConverter-class.html
2) Use `JsonKey` fields `fromJson` and `toJson`
  https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html
  https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html
3) Set `JsonSerializable.genericArgumentFactories` to `true`
  https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/genericArgumentFactories.html
package:<???>/models/itinerary_data.freezed.dart:253:17
    ╷
253 │   final List<T> summary;
    │                 ^^^^^^^
    ╵
[INFO] Running build completed, took 221ms

我确实尝试过添加转换器,如下所示:

class ItineraryDataConverter
    implements JsonConverter<ItineraryData, Map<String, dynamic>> {
  const ItineraryDataConverter();

  @override
  ItineraryData fromJson(Map<String, dynamic> json) {
    if (json == null || !json.containsKey('data')) {
      return null;
    }

    json = json['data'];
    // type data was already set (e.g. because we serialized it ourselves)
    if (!json.keys
        .any((k) => ['cabin_class', 'hotel', 'car_type'].contains(k))) {
      return ItineraryData.fromJson(json);
    }
    // you need to find some condition to know which type it is. e.g. check the presence of some field in the json
    if (json.containsKey('cabin_class')) {
      return _FlightItineraryData.fromJson(json);
    } else if (json.containsKey('hotel')) {
      return _HotelItineraryData.fromJson(json);
    } else if (json.containsKey('car_type')) {
      return _CarItineraryData.fromJson(json);
    } else {
      throw Exception(
          'Could not determine the constructor for mapping from JSON');
    }
  }

  @override
  Map<String, dynamic> toJson(ItineraryData data) => data.toJson();
}

但我仍然遇到同样的错误。

我如何确保summary 是可见的 + 子类的强类型?

或者更好的方法是什么?

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    您是否尝试为 T 类型添加自定义转换器?

    const factory ItineraryData({
      @CustomConverter() List<T> summary,
      ...
    
    
    ...
    
    class CustomConverter<T> implements JsonConverter<T, Object> {
      const CustomConverter();
    
      @override
      T fromJson(Object json) {
        // TODO: implement fromJson
        throw UnimplementedError();
      }
    
      @override
      Object toJson(T object) {
        // TODO: implement toJson
        throw UnimplementedError();
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-21
      • 2020-11-26
      • 2022-08-06
      • 1970-01-01
      • 2012-07-14
      相关资源
      最近更新 更多