【问题标题】:Dart / Flutter: Mapping json to object having a base class using fromJson in base objectDart / Flutter:在基对象中使用 fromJson 将 json 映射到具有基类的对象
【发布时间】:2021-01-28 17:43:08
【问题描述】:

我有两个类:BaseClass (BaseResponse) 和 DerivedClass (LoginResponse)。我正在使用 fromJson 方法对它们进行反序列化。

我想了解如何调用基类的 fromJson 方法。

class BaseResponse { 
  int responseCode;
  String responseMessage;

  BaseResponse.fromJson(Map<String, dynamic> input)
      : responseCode = input["ResponseCode"],        
        responseMessage = input["ResponseMessage"];
}
class LoginResponse extends BaseResponse {
    String authenticationToken;
    
    LoginResponse.fromJson(Map<String, dynamic> input) 
      : authenticationToken = input["AuthenticationToken"];

}

LoginResponse.fromJson(Map&lt;String, dynamic&gt; input) 给我一个错误提示:“BaseResponse”类没有未命名的构造函数。

感谢任何帮助。

谢谢。

【问题讨论】:

    标签: flutter dart fromjson


    【解决方案1】:

    base 类中定义构造函数。

    BaseResponse({required this.responseCode, required this.responseMessage});
    

    派生类中

    LoginResponse(
          {required this.authenticationToken,
          required int responseCode,
          required String responseMessage})
          : super(responseCode: responseCode, responseMessage: responseMessage);
    

    LoginResponse.fromJson 添加为factory 并使用LoginResponse 的构造函数。

    factory LoginResponse.fromJson(Map<String, dynamic> input) => LoginResponse(
              authenticationToken: input['AuthenticationToken'],
              responseCode: input['ResponseCode'],
              responseMessage: input['ResponseMessage']);
    

    类应该是这样的:

    class BaseResponse {
      int responseCode;
      String responseMessage;
    
      BaseResponse({required this.responseCode, required this.responseMessage});
    
      BaseResponse.fromJson(Map<String, dynamic> input)
          : responseCode = input["ResponseCode"],
            responseMessage = input["ResponseMessage"];
    }
    
    class LoginResponse extends BaseResponse {
      String authenticationToken;
    
      LoginResponse(
          {required this.authenticationToken,
          required int responseCode,
          required String responseMessage})
          : super(responseCode: responseCode, responseMessage: responseMessage);
    
      factory LoginResponse.fromJson(Map<String, dynamic> input) => LoginResponse(
          authenticationToken: input['AuthenticationToken'],
          responseCode: input['ResponseCode'],
          responseMessage: input['ResponseMessage']);
    }
    

    【讨论】:

      【解决方案2】:

      除非您出于某种原因绝对需要它,否则我不会为 BaseResponse 制作 .fromJson。

      我认为更好的方法是在基类中声明最终变量并在那里断言表达式,并且只在派生类中实现模型或任何类型:

      class BaseResponse { 
        final int responseCode;
        final String responseMessage;
      
        BaseResponse({@required this.responseCode, @required this.responseMessage)
        : assert(<expression>);
      }
      
      class LoginResponse extends BaseResponse {
        final String authenticationToken;
        final int code;
        final String message;
         
        LoginResponse({
          this.authenticationToken,
          this.code,
          this.message,
        }) : super(code: code, message: message)
      
        LoginResponse.fromJson(Map<String, dynamic> input) {
          return LoginResponse(
          authenticationToken: input['token'],
          code: input['code'],
          message: input['message'],
          );
        }
      
      }
      

      【讨论】:

      • 感谢您的回复。好吧,我不确定我们为什么要在派生类中重新声明变量。我在 base 中实现了 fromJson 的功能,所以我不必担心它们的实现。我只是在派生类中声明新字段,使用它们,对它们进行序列化和反序列化,并将剩余的工作留给基类。有什么想法吗。我来自 C# 背景,所以请原谅我对 Dart / Flutter 的有限了解。
      • 当然,现在我明白了基类和派生类的含义,答案可能需要稍作调整。您是否考虑过拥有一个带有声明但没有实现的基类(如答案中所示),一个具有上述实现的扩展(BaseClassModel),然后是任意数量的派生类(例如 LoginResponse),它可以扩展模型类,从而使您能够控制 BaseClass 的任何更新,同时保持核心清洁和每个派生类的模型唯一。这个答案基于 Flutter 中的简洁架构方法。
      【解决方案3】:

      BaseResponse 使用 url 发布数据,参数 json 正文:

      Future<dynamic> postData(String _url, dynamic _body, {@required latlng = null}) async {
          BaseResponse responseJson;
          try {
            Uri url = Uri.parse(_url);
            latlng = latlng ?? '93.2548,23.5987';
            var headers = {"latLng": "$latlng", "Content-Type": "application/json", 'Authorization': 'Bearer ${CtsSharedPreferences.getString('token')}'};
            final response = await post(url, headers: headers, body: _body);
            responseJson = _returnResponse(response);
          } on SocketException {
            throw FetchDataException('No Internet connection');
          }
          return responseJson;
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-19
        • 2017-12-24
        • 1970-01-01
        • 1970-01-01
        • 2019-05-27
        • 1970-01-01
        • 2012-11-17
        • 2014-11-07
        相关资源
        最近更新 更多