BLoC Flutter中的事件问题.我总是把两个事件称为一个事件



我在每个块方法中使用TodoLoadedState列表返回状态。但是当我在onPressed中调用块事件时,列表本身不会返回,我必须添加第二个对块方法todoBloc.add(LoadTodos(((的调用;但这是不对的。想法需要触发1个事件,但要执行2个操作,第二个操作是更新列表。提前感谢!

todo_block

class TodoBloc extends Bloc<TodoEvent, TodoState> {
final TodoRepository todoRepository;
TodoBloc(this.todoRepository) : super(TodoEmptyState()) {
on<LoadTodos>((event, emit) async {
emit(TodoLoadingState());
try {
final List<Todo> _loadedTodoList = await todoRepository.getAllTodos();
emit(TodoLoadedState(loadedUser: _loadedTodoList));
} catch (_) {
emit(TodoErrorState());
}
});
on<CreateTodos>((event, emit) async {
// Todo todo = Todo(description: event.task, isDone: false);
await todoRepository.insertTodo(event.todo);
final List<Todo> _loadedTodoList = await todoRepository.getAllTodos();
emit(TodoLoadedState(loadedUser: _loadedTodoList));
});
on<DeleteTodos>((event, emit) async {
await todoRepository.deleteTodo(event.id);
final List<Todo> _loadedTodoList = await todoRepository.getAllTodos();
emit(TodoLoadedState(loadedUser: _loadedTodoList));
});
on<UpdateTodos>((event, emit) async {
await todoRepository.updateTodo(event.todo);
final List<Todo> _loadedTodoList = await todoRepository.getAllTodos();
emit(TodoLoadedState(loadedUser: _loadedTodoList));
});
}
}

todo_list

class TodoList extends StatelessWidget {
@override
Widget build(BuildContext context) {
final TodoBloc todoBloc = context.read<TodoBloc>();
return BlocBuilder<TodoBloc, TodoState>(builder: (context, state) {
if (state is TodoEmptyState) {
return const Center(
child: Text(
'No Todo',
style: TextStyle(fontSize: 20.0),
),
);
}
if (state is TodoLoadingState) {
return const Center(child: CircularProgressIndicator());
}
if (state is TodoLoadedState) {
return ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: state.loadedUser.length,
itemBuilder: (context, index) => ListTile(
title: Column(children: [
Text('${state.loadedUser[index].description}'),
Text('${state.loadedUser[index].id}'),
]),
trailing: IconButton(
onPressed: () {
todoBloc.add(DeleteTodos(id: state.loadedUser[index].id));
todoBloc.add(LoadTodos());
},

主页页面

class HomePage extends StatelessWidget {
final todoRepository = TodoRepository();
@override
Widget build(BuildContext context) {
return BlocBuilder<TodoBloc, TodoState>(builder: (context, state) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Todos'),
),
body: SingleChildScrollView(
child: Column(
children: [
TodoList(),
],
),
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add, size: 32, color: Colors.white),
onPressed: () {
final TodoBloc todoBloc = context.read<TodoBloc>();
final _todoDescriptionFromController = TextEditingController();
showModalBottomSheet(
context: context,
builder: (builder) {
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Container(
color: Colors.transparent,
child: Container(

todo_state

abstract class TodoState extends Equatable {
const TodoState();
@override
List<Object> get props => [];
}
class TodoLoadingState extends TodoState {}
class TodoEmptyState extends TodoState {}
class TodoLoadedState extends TodoState {
List<dynamic> loadedUser;
TodoLoadedState({required this.loadedUser});
}
class TodoErrorState extends TodoState {}

todo_event

abstract class TodoEvent extends Equatable {
const TodoEvent();
@override
List<Object> get props => [];
}
class LoadTodos extends TodoEvent {}
class CreateTodos extends TodoEvent {
final Todo todo;
const CreateTodos(this.todo);
}
class UpdateTodos extends TodoEvent {
final Todo todo;
const UpdateTodos(this.todo);
}
class DeleteTodos extends TodoEvent {
final int id;
const DeleteTodos({required this.id});
}
class QueryTodo extends TodoEvent {}

event on按下,在任何地方都必须使用2个事件来加载更新的列表

todoBloc.add(UpdateTodos(updateTodo));
todoBloc.add(LoadTodos());

这就是罪魁祸首:

abstract class TodoState extends Equatable {
const TodoState();
@override
List<Object> get props => [];
}

您正在TodoState中扩展Equatable,并将一个空列表传递给props。当其他状态(如TodoLoadedState(扩展TodoState时,它们也继承Equatable和空道具。

如果使用Equatable,请确保将所有属性传递给道具吸气剂。

这是来自集团常见问题。现在,您的TodoLoadedState的所有实例都被认为是相等的。不管你有一个有数百个loadedUserTodoLoadedState还是一个没有的TodoLoadedState。它们都被认为是相等的,只有当您第一次通过新的TodoLoadedState时,BlocBuilder才会更新。由于BlocBuilder认为其与前一个相同,因此后一个没有影响。LoadTodos事件导致重建的原因是,首先发出TodoLoadingState(),然后在成功的情况下发出TodoLoadedState(loadedUser: _loadedTodoList)。两种不同状态之间的交替使其起作用。

因此,要么不要使用Equatable,要么确保将所有属性传递给props

class TodoLoadedState extends TodoState {
final List<dynamic> loadedUser;
TodoLoadedState({required this.loadedUser});
@override
List<Object?> get props => [loadedUser];
}

最新更新