При использовании isar с зависанием появляется ошибка неподдерживаемого типа для метода getter copyWith во время выполнения сборки.
Вот класс модели, для которого build_runner не работает.
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:isar/isar.dart';
part 'api_response_model.freezed.dart';
part 'api_response_model.g.dart';
@collection
@freezed
class ApiResponseModel with _$ApiResponseModel {
const ApiResponseModel._();
factory ApiResponseModel({
@JsonKey(name: 'data') String? data,
}) = ResponseModel;
Id get id => Isar.autoIncrement;
factory ApiResponseModel.fromJson(Map<String, Object?> json) =>
_$ApiResponseModelFromJson(json);
}
Вот ошибка, возникающая при выполнении команды build_runner.
Unsupported type. Please annotate the property with @ignore.
package:freezed_isar/api_response_model.freezed.dart:28:51
╷
28 │ $ApiResponseModelCopyWith<ApiResponseModel> get copyWith =>
│ ^^^^^^^^
╵





Будет конфликт.
Когда мы создаем коллекцию для «isar», она генерирует файл «g.dart», а при использовании fromJson (замороженный) также генерирует файл «g.dart».
Альтернативное решение:
Используйте расширение vs code: генератор классов данных dart
Создайте свою коллекцию isar следующим образом:
import 'package:isar/isar.dart';
part 'api_response_model.g.dart';
@collection
class ApiResponseModel {
Id? id = Isar.autoIncrement;
@Index(type: IndexType.value)
String? data;
}
Наведите курсор на имя класса и нажмите значок подсказки (или нажмите «cmd + .»), чтобы отобразить параметры для создания класса данных:
Затем нажмите «Создать класс данных», после чего будут созданы все необходимые методы для класса данных, такие как toMap(), fromMap(), copyWith(), toJson(), fromJson() и т. д.
Сгенерированный код покажет две ошибки: одну в «toMap()», а другую в «fromMap()». Чтобы решить эту проблему, нам нужно изменить параметр «id» для обоих методов.
Сгенерированные методы:
Map<String, dynamic> toMap() {
return <String, dynamic>{
'id': id?.toMap(),
'data': data,
};
}
factory ApiResponseModel.fromMap(Map<String, dynamic> map) {
return ApiResponseModel(
id: map['id'] != null ? Id.fromMap(map['id'] as Map<String,dynamic>) : null,
data: map['data'] != null ? map['data'] as String : null,
);
}
Обновленные методы:
Map<String, dynamic> toMap() {
return <String, dynamic>{
'id': id,
'data': data,
};
}
factory ApiResponseModel.fromMap(Map<String, dynamic> map) {
return ApiResponseModel(
id: map['id']?.toInt(),
data: map['data'] != null ? map['data'] as String : null,
);
}
Наконец, просто запустите команду build runner, чтобы сгенерировать файл g.dart для isar. (это можно сделать до создания функций copyWith()).
Теперь ваш класс данных создан, и его также можно использовать для сбора isar и преобразования данных.
В приведенном выше решении: мы не изменяем сгенерированные файлы. Мы просто создаем некоторые необходимые функции, такие как copyWith(), внутри класса модели, а не в файлах g.dart.
Я плохо понял, что вы упомянули об изменении файла .g.dart. Однако вместо этого небольшого длительного процесса использование параметра «игнорировать» аннотации Collection решает эту проблему.
Где я упоминал об изменении файла g.dart?
Тип функции copyWith, созданный freezed, не поддерживается isar. Чтобы игнорировать copyWith, вы можете использовать аннотацию @collection isar следующим образом:
@Collection(ignore: {'copyWith'})
Изменение сгенерированных файлов не рекомендуется, так как если мы снова запустим команду или перегенерируем указанным способом (даже для вновь добавленных файлов), сгенерированные файлы будут перегенерированы, а изменения потеряются. Кроме того, в соответствии с рекомендациями сгенерированные файлы (.g.dart) не передаются в VCS.