Gal*_*ose 4 null dart flutter bloc flutter-bloc
How do you deal with "accepted null values" when you update a state in BLoC ? I use the flutter_bloc package.
I have a form in which numeric variables are nullable so that I can check their validity before the form is submitted. But when I emit a new state, I use state.copyWith(var1?, var2?)... so when a null value is used to update a parameter, the value is not updated.
To face that I use a custom FieldStatus enum for each field. In my form submission, I can check the status of each field. But this is a bit verbose... and it needs to use 2 values instead of 1 for each field, which is not very satisfying.
I can also force the value to be null according to the new value of its FieldStatus, but it is a bit tricky and not very satisfying.
How would you manage such a case ?
Here is what I did :
States :
part of 'phhfgroup_bloc.dart';
class PhhfGroupState extends Equatable
{
final double? height;
final FieldStatus heightStatus;
const PhhfGroupState({this.height, this.heightStatus = FieldStatus.initial});
@override
List<Object?> get props => [height, heightStatus];
PhhfGroupState copyWith({double? height, FieldStatus? heightStatus})
{
return PhhfGroupState(
height: height ?? this.height,
heightStatus: heightStatus ?? this.heightStatus
);
}
}
Run Code Online (Sandbox Code Playgroud)
Events :
part of 'phhfgroup_bloc.dart';
abstract class PhhfGroupEvent extends Equatable
{
const PhhfGroupEvent();
@override
List<Object> get props => [];
}
class HeightChanged extends PhhfGroupEvent
{
const HeightChanged({required this.height});
final String height;
@override
List<Object> get props => [height];
}
Run Code Online (Sandbox Code Playgroud)
Handler :
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:myapp/models/statuses.dart';
part 'phhfgroup_event.dart';
part 'phhfgroup_state.dart';
class PhhfGroupBloc extends Bloc<PhhfGroupEvent, PhhfGroupState>
{
PhhfGroupBloc() : super()
{
on<HeightChanged>(_mapHeightEventToState);
}
void _mapHeightEventToState(HeightChanged event, Emitter<PhhfGroupState> emit)
{
if(event.height.isEmpty)
{
emit(this.state.copyWith(
height: null,
heightStatus: FieldStatus.empty
));
}
else
{
double? height = double.tryParse(event.height);
if(height == null)
emit(this.state.copyWith(
height: null,
heightStatus: FieldStatus.nonnumeric
));
else emit(this.state.copyWith(
height: height,
heightStatus: FieldStatus.numeric
));
}
}
}
Run Code Online (Sandbox Code Playgroud)
Thanks !
无夜之*_*之星辰 11
另一种方式,您可以使用ValueGetter
.
例如,password
如下:
@immutable
class LoginPageState {
const LoginPageState({
this.phone,
this.password,
});
final String? phone;
final String? password;
LoginPageState copyWith({
String? phone,
ValueGetter<String?>? password,
}) {
return LoginPageState(
phone: phone ?? this.phone,
password: password != null ? password() : this.password,
);
}
}
Run Code Online (Sandbox Code Playgroud)
设置:password
null
void resetPassword() {
final newState = state.copyWith(password: () => null);
emit(newState);
}
Run Code Online (Sandbox Code Playgroud)
您不需要任何额外的标志或包。
通过使用freeze,您可以执行以下操作:
void main() {
var person = Person('Remi', 24);
// `age` not passed, its value is preserved
print(person.copyWith(name: 'Dash')); // Person(name: Dash, age: 24)
// `age` is set to `null`
print(person.copyWith(age: null)); // Person(name: Remi, age: null)
}
Run Code Online (Sandbox Code Playgroud)
如果您不想使用其他包,我建议添加一个参数来控制可为空值。
class PhhfGroupState extends Equatable
{
final double? height;
final FieldStatus heightStatus;
const PhhfGroupState({this.height, this.heightStatus = FieldStatus.initial});
@override
List<Object?> get props => [height, heightStatus];
PhhfGroupState copyWith({double? height, FieldStatus? heightStatus, bool clearHeight = false})
{
return PhhfGroupState(
height: clearHeight == true ? null : height ?? this.height,
heightStatus: heightStatus ?? this.heightStatus
);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您有一堆nullable
字段,我强烈建议freeze,但对于其他字段,只需为其添加一个标志即可。
归档时间: |
|
查看次数: |
3763 次 |
最近记录: |