Flutter中如何为含嵌套rating字段的API数据创建正确数据模型
问题原因
你当前的代码存在两个核心错误:
- 错误将嵌套在
rating下的rate、count字段定义为Product的顶层属性,这两个字段实际属于rating对象,不应该出现在Product的构造参数中。 - 给
rating声明的Map<double, int>类型和实际结构完全不匹配:你传入的{rate: 2.1, count: 430}是key为字符串、value包含多种类型的结构,Dart的Map要求key类型统一、value类型统一,这种固定字段名的嵌套结构不能用强类型Map直接接收。
正确实现方式
和TypeScript中定义嵌套interface的逻辑一致,Dart中遇到固定结构的嵌套对象,需要单独为嵌套结构定义对应的数据类。
- 首先定义
Rating类,承接rate和count两个字段:
class Rating { final double? rate; final int? count; Rating({this.rate, this.count}); }
- 修改
Product类,移除冗余的顶层rate、count字段,将rating的类型改为Rating?:
class Product { final int? id; final String? title; final double? price; final String? description; final String? category; final String? image; final Rating? rating; Product({ this.id, this.title, this.price, this.description, this.category, this.image, this.rating, }); }
- 实例化
Product时,给rating传入Rating类的实例即可,不会再触发报错:
List<Product> productsList = [ Product( id: 1, title: "Blue Bag", price: 100, description: " this is a description", category: "Clothes", image: "https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg", rating: Rating(rate: 2.1, count: 430) ) ];
扩展:对接API的JSON转换实现
如果后续需要解析接口返回的JSON数据,可以给两个类添加fromJson工厂构造函数,直接把Map格式的JSON数据转成类型安全的模型对象:
class Rating { final double? rate; final int? count; Rating({this.rate, this.count}); factory Rating.fromJson(Map<String, dynamic> json) { return Rating( // 调用toDouble()兼容接口返回int类型分值的情况 rate: json['rate']?.toDouble(), count: json['count'] as int?, ); } } class Product { final int? id; final String? title; final double? price; final String? description; final String? category; final String? image; final Rating? rating; Product({ this.id, this.title, this.price, this.description, this.category, this.image, this.rating, }); factory Product.fromJson(Map<String, dynamic> json) { return Product( id: json['id'] as int?, title: json['title'] as String?, price: json['price']?.toDouble(), description: json['description'] as String?, category: json['category'] as String?, image: json['image'] as String?, // rating字段不为空时才调用Rating的fromJson方法解析 rating: json['rating'] != null ? Rating.fromJson(json['rating']) : null, ); } }
注意:如果硬要用Map类型接收rating字段,只能声明为
Map<String, dynamic>,但这种写法会丢失静态类型校验,取字段时很容易出现拼写错误、类型不匹配问题,生产环境不推荐使用。
内容的提问来源于stack exchange,提问作者Oren Papa
相关产品推荐
相关产品推荐

