@freezed copyWith missing с запечатанными классами
В следующем фрагменте функция state.copyWith недоступна.
@freezed
class MyState with _$MyState {
@JsonSerializable(fieldRename: FieldRename.snake, explicitToJson: true)
const factory MyState({@Default(0) int counter,}) = _MyState;
const factory MyState.initial({@Default(0) int counter}) = Initial;
const factory MyState.loading() = Loading;
const factory MyState.one() = One;
const factory MyState.two() = Two;
factory MyState.fromJson(Map<String, dynamic> json) =>
_$MyStateFromJson(json);
}
class MyStateNotifier extends StateNotifier<MyState> {
MyStateNotifier() : super(MyState.initial());
Future<void> one() async {
state = MyState.loading();
await Future.delayed(Duration(seconds: 5));
state.copyWith(counter: 1);
}
}
Однако, когда я удаляю запечатанные классы, функция copyWith становится доступной.
@freezed
class MyState with _$MyState {
@JsonSerializable(fieldRename: FieldRename.snake, explicitToJson: true)
const factory MyState({@Default(0) int counter,}) = _MyState;
// const factory MyState.initial({@Default(0) int counter}) = Initial;
// const factory MyState.loading() = Loading;
// const factory MyState.one() = One;
// const factory MyState.two() = Two;
factory MyState.fromJson(Map<String, dynamic> json) =>
_$MyStateFromJson(json);
}
class MyStateNotifier extends StateNotifier<MyState> {
MyStateNotifier() : super(MyState());
Future<void> one() async {
await Future.delayed(Duration(seconds: 5));
state.copyWith(counter: 1);
}
}
Что мне нужно изменить, чтобы copyWith стал доступен в первом фрагменте?
2 ответа
Только свойства, общие для всех конструкторов, будут генерировать метод, как указано в документации README.
You also can use copyWith with properties defined on all constructors...
Представьте, что у вас есть экземпляр
Loading
, какой метод вы ожидаете от этого? У него нет свойств, следовательно, у него не может быть никаких методов, поэтому не может быть и объединение всех типов.
Однако вы можете использовать сопоставление с образцом для вызова
copyWith
на экземплярах правильного типа.
В вашем примере будет работать что-то вроде этого:
MyState myState = ...;
myState.maybeMap(
initial: (v: Initial) => v.copyWith(counter: v.counter + 1),
orElse: () => ...,
);
Или используя
when
:
MyState myState = ...;
myState.when(
(int counter) => MyState.initial(counter + 1),
loading: () => loading,
one: () => one,
two: () => two,
);
вы можете получить доступ к методу copyWith, выполните преобразование типа:
`if (состояние CurrentState) {final myState = состояние как CurrentState}
myState.copyWith (...)`