Сериализация Flutter JSON - файлы *.g.dart не создаются
Я новичок в флаттере, и цель состоит в том, чтобы сериализовать сложные объекты JSON, содержащие другие более мелкие объекты.
Используя json_serializable: ^2.0.0
и pubspec.yaml
файл выглядит примерно так.
dependencies:
intl: ^0.15.7
json_annotation: ^2.0.0
built_value: ^6.7.1
flutter:
sdk: flutter
dev_dependencies:
build_runner: ^1.0.0
json_serializable: ^2.0.0
built_value_generator: ^6.7.1
flutter_test:
sdk: flutter
В user.dart
выглядеть так
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable(nullable: false)
class User {
final String firstName;
final String lastName;
final DateTime dateOfBirth;
User({this.firstName, this.lastName, this.dateOfBirth});
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
я пытался flutter pub run build_runner build
но файл user.g.dart не создается, и я столкнулся с проблемой.
Я также добавил build.yaml
файл со следующим кодом
targets:
$default:
builders:
built_value_generator|built_value:
generate_for:
- model/*.dart
json_serializable|json_serializable:
generate_for:
- model/*.dart
Может ли кто-нибудь сообщить мне, что мне здесь не хватает. Спасибо
14 ответов
Аргумент конструктора не должен быть необязательным
User({this.firstName, this.lastName, this.dateOfBirth});
Они должны быть обязательными:
User(this.firstName, this.lastName, this.dateOfBirth);
И часть
'user.g.dart';
должен соответствовать классу Uppercase User:
part 'User.g.dart';
Контрольный список
- ваши файлы классов находятся под /lib или /bin
- могут быть подкаталогами в этих
- json_serializable не будет искать файлы для создания в каждом каталоге.
- вы добавили
part
директива послеimport
заявления- ваш
part
файл с именем после вашего класса файла (а не имя класса самого), сg
добавлено - например, для
CacheItem
класс с... cache-item.dart
имя файла класса...part 'cache-item.g.dart';
получает соответствующийpart
директива.- то
part
Директива названа не в честь вашего фактического класса, а в честь имени файла класса.
- ваш
- вы добавили
@JsonSerializable()
над названием класса - вы создали конструктор по умолчанию для своего класса.
- Он может быть пустым, иметь необязательные именованные параметры или позиционные параметры.
- Пока поля вашего класса доступны (либо через конструктор, либо через общедоступные сеттеры и геттеры), json_serializable может справиться с этим. (т.е. не иметь только свойств _private и пустого конструктора)
- вы написали методы-заглушки:
factory <Class>.fromJson(json) => _$ClassFromJson(json);
toJson() => _$ClassToJson(this)
- методы-заглушки являются частными (начинаются с
_
нижнее подчеркивание) - методы $tub имеют
$
- методы-заглушки имеют правильный CaSe (т.е. регистр Паскаля)
- заглушка
factory
поставки(Map<String,dynamic> json)
как аргумент - заглушка
toJson()
возвращаетсяMap<String,dynamic>
Когда все будет готово, попробуйте запустить генератор из корневого каталога проекта...
Во флаттере:
flutter pub run build_runner build
В чистом дротике:
pub run build_runner build
Пример проекта на github, соответствующие файлы в /bin/ и пакеты в pubspec.yaml
Справочные материалы и документы
- Флаттер и Json
- Пакет Json_Serializable
- Пример от авторов пакета
пример
import 'package:json_annotation/json_annotation.dart';
part 'cache-item.g.dart';
@JsonSerializable()
class CacheItem {
int created;
String keywords;
String response;
CacheItem(this.created, this.keywords, this.response);
factory CacheItem.fromJson(Map<String,dynamic> json) => _$CacheItemFromJson(json);
Map<String,dynamic> toJson() => _$CacheItemToJson(this);
}
Выход
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'cache-item.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
CacheItem _$CacheItemFromJson(Map<String, dynamic> json) {
return CacheItem(
json['created'] as int,
json['keywords'] as String,
json['response'] as String,
);
}
Map<String, dynamic> _$CacheItemToJson(CacheItem instance) => <String, dynamic>{
'created': instance.created,
'keywords': instance.keywords,
'response': instance.response,
};
Пример варианта конструктора
Этот пример такой же, как и выше, за исключением того, что в конструкторе отсутствуют некоторые поля и есть response
как необязательный.
Это замечательно.
Генератор будет просто использовать общедоступные (неявные) геттеры после создания экземпляра объекта для присвоения значений.
import 'package:json_annotation/json_annotation.dart';
part 'cache-item.g.dart';
@JsonSerializable()
class CacheItem {
int created;
String keywords;
String response;
CacheItem({this.response});
factory CacheItem.fromJson(Map<String,dynamic> json) => _$CacheItemFromJson(json);
Map<String,dynamic> toJson() => _$CacheItemToJson(this);
}
Выход
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'cache-item.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
CacheItem _$CacheItemFromJson(Map<String, dynamic> json) {
return CacheItem(
response: json['response'] as String,
)
..created = json['created'] as int
..keywords = json['keywords'] as String;
}
Map<String, dynamic> _$CacheItemToJson(CacheItem instance) => <String, dynamic>{
'created': instance.created,
'keywords': instance.keywords,
'response': instance.response,
};
попробуйте бежать
>flutter packages pub run build_runner build --delete-conflicting-outputs
Если вы пытаетесь сгенерировать файлы .g, просто запустив команду, и вы не получаете желаемого результата, просто попробуйте:
flutter clean
«восстановление кеша флаттер-паба»
flutter packages pub run build_runner build --delete-conflicting-outputs
удалить все временные файлы Gradle
затем беги
flutter pub get
flutter packages pub run build_runner build
.
Я столкнулся с той же проблемой и попробовал все упомянутые выше предложения, но ничего не помогло. После нескольких часов борьбы, я узнал, что файл должен быть сохранен перед запуском команды.
- пакеты флаттера pub run build_runner build
Я знаю, что ответ такой простой, но вы сохранили файл перед запуском команды
добавление
json_serializable: ^6.0.0
to dev_dependencies решить это для меня
в моем случае мне пришлось добавить пакет hive_generator вместе с пакетом build_runner. Если имя класса вашей модели, например, transaction.dart, то оно будет таким:
part 'transaction.g.dart'
Запустите команду-
flutter packages pub run build_runner build
он сгенерирует для вас модель транзакции.
У меня была следующая ошибка
ошибка
[WARNING] json_serializable:json_serializable on lib/day10/models/sentence.dart:
Missing "part 'sentence.g.dart';".
Я заметил, что мне пришлось изменить в файле модели это part 'Sentence.g.dart';
к этому part 'sentence.g.dart';
другими словами, мне нужно было записать его в нижний регистр.
пожалуйста, проверьте свой
part file name
, например:
если имя вашего файла dartuser_model.dart
, ваша часть «xxx.g.dart» должна быть:
part 'user_model.g.dart'
это сработало для моего проекта. Для меня после части xxx.g.dart должно быть имя файла .dart, а не имя класса.
В моем случае проблема заключалась в том, что я неправильно написал имя метода. Я написал formJson вместо fromJson.
factory MyClass.formJson(Map<String, dynamic> json) =>
_$MyClassFromJson(json);
должно было :
factory MyClass.fromJson(Map<String, dynamic> json) =>
_$MyClassFromJson(json);
Несколько раз мы забывали сохранить файлы, пожалуйста, сохраните файл, а затем запустите команду.
flutter packages pub run build_runner build
Шаг 1: Добавьте «часть 'your_class_name.g.dart'»
Шаг 2: Запустите эту команду в терминале: flutter pub run build_runner build
Пример:
part 'student.g.dart'
@JsonSerializable()
class Student{
....
}
Не забудьте сохранить файл с расширениемclass
даже если он все еще имеет ошибки
Затем запустите команду на любом терминале (или встроенном терминале)...
Но для Дарта:
pub run build_runner build
И для флаттера:
flutter pub run build_runner build
Официальная справочная ссылка: