如何用json_serializable为PerFieldToJson生成父类category字段方法?
解决Firestore ODM生成代码缺失父类字段的问题
问题根源
_$FooPerFieldToJson只生成子类Foo的age字段,是因为父类Bar未被@JsonSerializable注解标记,导致依赖json_serializable实现字段映射的Firestore ODM代码生成器,无法识别父类的category字段,进而不会将其纳入perFieldToJson和字段映射逻辑中。
解决方案
要让父类字段被生成器识别,需完成以下步骤:
1. 为父类Bar添加序列化配置
给Bar类添加@JsonSerializable注解,并声明对应的part文件,让json_serializable为它生成序列化代码:
// bar.dart import 'package:json_annotation/json_annotation.dart'; part 'bar.g.dart'; @JsonSerializable() abstract class Bar { final String category; Bar({required this.category}); // 声明序列化方法,触发生成器处理父类字段 factory Bar.fromJson(Map<String, dynamic> json) => _$BarFromJson(json); Map<String, dynamic> toJson() => _$BarToJson(this); }
2. 修改子类Foo的序列化配置
在Foo的@JsonSerializable中添加useSuperKeys: true,确保生成器将父类字段纳入子类逻辑;同时声明子类的序列化方法并关联父类逻辑:
// foo.dart import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore_odm/cloud_firestore_odm.dart'; import 'package:json_annotation/json_annotation.dart'; import 'bar.dart'; part 'foo.g.dart'; @JsonSerializable( createFieldMap: true, createPerFieldToJson: true, useSuperKeys: true, // 关键:启用父类字段的序列化支持 ) class Foo extends Bar { final int age; Foo(this.age) : super(category: 'c'); // 生成子类序列化方法,关联父类逻辑 factory Foo.fromJson(Map<String, dynamic> json) => _$FooFromJson(json); @override Map<String, dynamic> toJson() => _$FooToJson(this); } @Collection<Foo>('foo') final fooRef = FooCollectionReference();
3. 重新执行代码生成命令
运行dart run build_runner build -d,此时生成的foo.g.dart中,_$FooPerFieldToJson会包含category字段的处理方法:
// foo.g.dart abstract class _$FooPerFieldToJson { // ignore: unused_element static Object? age(int instance) => instance; // ignore: unused_element static Object? category(String instance) => instance; }
同时whereCategory方法中的_$FooPerFieldToJson.category()调用也能正常工作,不会再报错。
补充说明
useSuperKeys: true是让json_serializable将父类字段纳入子类字段映射和序列化逻辑的核心配置。- 父类必须显式声明
fromJson和toJson方法,否则生成器无法为父类生成对应的序列化代码,子类也无法继承处理父类字段。
内容的提问来源于stack exchange,提问作者iDecode
相关产品推荐
相关产品推荐

