将默认 Flutter_bloc 8.0 计数器从 Cubit 转换为 Bloc
Convert Default Flutter_bloc 8.0 Counter from Cubit to Bloc
我正在尝试将 bloc 的简单 cubit 示例转换为 bloc 模式,但是当我按下增量按钮时出现 ...NoSuchMethodError: Class '_Emitter<MyObjectState>...
错误。
我认为我的问题是我用于 emit
参数的 dynamic
类型(将其更改为 MyObjectState
会导致表达式不是函数的错误)。
那应该是什么,这是我唯一的问题吗?
class MyObjectBloc extends Bloc<MyObjectEvent, MyObjectState> {
MyObjectBloc() : super(const MyObjectState(counter: 99)) {
on<AddEvent>(_onIncrement);
on<SubtractEvent>(_onDecrement);
}
void _onIncrement(AddEvent event, dynamic emit) => emit(counter: state.counter + 1);
void _onDecrement(SubtractEvent event, dynamic emit) => emit(counter: state.counter - 1);
}
abstract class MyObjectEvent {
const MyObjectEvent();
}
class AddEvent extends MyObjectEvent {}
class SubtractEvent extends MyObjectEvent {}
class MyObjectState {
const MyObjectState({required this.counter});
final int counter;
}
class CounterPage extends StatelessWidget {
const CounterPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => MyObjectBloc(),
child: CounterView(),
);
}
}
class CounterView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
return Scaffold(
body: Center(
child: BlocBuilder<MyObjectBloc, MyObjectState>(
builder: (context, state) {
return Text('${state.counter}', style: textTheme.headline2);
},
),
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () => context.read<MyObjectBloc>().add(AddEvent()),
),
FloatingActionButton(
child: const Icon(Icons.remove),
onPressed: () => context.read<MyObjectBloc>().add(SubtractEvent()),
),
],
),
);
}
}
这里的问题是你的emit
是错误的。
TLDR 答案
class MyObjectBloc extends Bloc<MyObjectEvent, MyObjectState> {
MyObjectBloc() : super(const MyObjectState(counter: 99)) {
on<AddEvent>(_onIncrement);
on<SubtractEvent>(_onDecrement);
}
void _onIncrement(AddEvent event, Emitter<MyObjectState> emit) => emit(MyObjectState(counter: state.counter + 1));
void _onDecrement(SubtractEvent event, Emitter<MyObjectState> emit) => emit(MyObjectState(counter: state.counter - 1));
}
abstract class MyObjectEvent {
const MyObjectEvent();
}
class AddEvent extends MyObjectEvent {}
class SubtractEvent extends MyObjectEvent {}
class MyObjectState {
const MyObjectState({required this.counter});
final int counter;
}
说明
如果我们仔细看看 on<EVENT>
,它是以下函数的函数:
void on<E extends Event>(
EventHandler<E, State> handler, {
EventTransformer<E>? transformer,
})
第一个参数是 EventHandler<E, State>
即:
typedef EventHandler<Event, State> = FutureOr<void> Function(
Event event,
Emitter<State> emit,
);
所以你应该发出你的状态 class。
我正在尝试将 bloc 的简单 cubit 示例转换为 bloc 模式,但是当我按下增量按钮时出现 ...NoSuchMethodError: Class '_Emitter<MyObjectState>...
错误。
我认为我的问题是我用于 emit
参数的 dynamic
类型(将其更改为 MyObjectState
会导致表达式不是函数的错误)。
那应该是什么,这是我唯一的问题吗?
class MyObjectBloc extends Bloc<MyObjectEvent, MyObjectState> {
MyObjectBloc() : super(const MyObjectState(counter: 99)) {
on<AddEvent>(_onIncrement);
on<SubtractEvent>(_onDecrement);
}
void _onIncrement(AddEvent event, dynamic emit) => emit(counter: state.counter + 1);
void _onDecrement(SubtractEvent event, dynamic emit) => emit(counter: state.counter - 1);
}
abstract class MyObjectEvent {
const MyObjectEvent();
}
class AddEvent extends MyObjectEvent {}
class SubtractEvent extends MyObjectEvent {}
class MyObjectState {
const MyObjectState({required this.counter});
final int counter;
}
class CounterPage extends StatelessWidget {
const CounterPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => MyObjectBloc(),
child: CounterView(),
);
}
}
class CounterView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
return Scaffold(
body: Center(
child: BlocBuilder<MyObjectBloc, MyObjectState>(
builder: (context, state) {
return Text('${state.counter}', style: textTheme.headline2);
},
),
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () => context.read<MyObjectBloc>().add(AddEvent()),
),
FloatingActionButton(
child: const Icon(Icons.remove),
onPressed: () => context.read<MyObjectBloc>().add(SubtractEvent()),
),
],
),
);
}
}
这里的问题是你的emit
是错误的。
TLDR 答案
class MyObjectBloc extends Bloc<MyObjectEvent, MyObjectState> {
MyObjectBloc() : super(const MyObjectState(counter: 99)) {
on<AddEvent>(_onIncrement);
on<SubtractEvent>(_onDecrement);
}
void _onIncrement(AddEvent event, Emitter<MyObjectState> emit) => emit(MyObjectState(counter: state.counter + 1));
void _onDecrement(SubtractEvent event, Emitter<MyObjectState> emit) => emit(MyObjectState(counter: state.counter - 1));
}
abstract class MyObjectEvent {
const MyObjectEvent();
}
class AddEvent extends MyObjectEvent {}
class SubtractEvent extends MyObjectEvent {}
class MyObjectState {
const MyObjectState({required this.counter});
final int counter;
}
说明
如果我们仔细看看 on<EVENT>
,它是以下函数的函数:
void on<E extends Event>(
EventHandler<E, State> handler, {
EventTransformer<E>? transformer,
})
第一个参数是 EventHandler<E, State>
即:
typedef EventHandler<Event, State> = FutureOr<void> Function(
Event event,
Emitter<State> emit,
);
所以你应该发出你的状态 class。