干净的 Riverpod 管理待办事项应用
使用 `Mixin Classes` 来组织 `Riverpod providers` 的 `scope` 使用,可以为全局 provider 管理提供一种改进且易于维护的结构,解决了全局管理 provider 所带来的弊端,并有助于 `维护` 和 `测试`。
本项目是基于 Riverpod 官方文档 中的“待办事项应用”开发的。
代码示例
状态 Mixin 类
mixin class HomeState {
///
/// Count of uncompleted todos.
///
int uncompletedTodosCount(WidgetRef ref) => ref.watch(uncompletedTodosCountProvider);
///
/// List of filtered todos.
///
List<Todo> filteredTodos(WidgetRef ref) => ref.watch(filteredTodosProvider);
///
/// Current todo. (Todo witch is focused)
///
Todo currentTodo(WidgetRef ref) => ref.watch(currentTodoProvider);
///
/// Current filter category for the todo list.
///
TodoListFilter todoListFilter(WidgetRef ref) => ref.watch(todoListFilterProvider);
}
事件 Mixin 类
mixin class HomeEvent {
///
/// Add a new todo to the list and clear the text input field.
///
void addTodo(
WidgetRef ref, {
required TextEditingController textEditingController,
required String value,
}) {
ref.read(todoListProvider.notifier).add(value);
textEditingController.clear();
}
///
/// Remove the selected todo from the list.
///
void removeTodo(WidgetRef ref, {required Todo selectedTodo}) {
ref.read(todoListProvider.notifier).remove(selectedTodo);
}
///
/// Request focus for the text input field and item focus node.
///
void requestTextFieldsFocus(
{required FocusNode textFieldFocusNode,
required FocusNode itemFocusNode}) {
itemFocusNode.requestFocus();
textFieldFocusNode.requestFocus();
}
///
/// Change the filter category for the todo list.
///
void changeFilterCategory(WidgetRef ref, {required TodoListFilter filter}) {
ref.read(todoListFilterProvider.notifier).state = filter;
}
///
/// Toggle the state (completed/incomplete) of a todo.
///
void toggleTodoState(WidgetRef ref, {required String todoId}) {
ref.read(todoListProvider.notifier).toggle(todoId);
}
///
/// Edit the description of a todo. If focused, set the description to the current value.
/// Otherwise, update the todo with the new description.
///
void editTodoDesc(WidgetRef ref,
{required bool isFocused,
required TextEditingController textEditingController,
required Todo selectedTodo}) {
if (isFocused) {
textEditingController.text = selectedTodo.description;
} else {
ref
.read(todoListProvider.notifier)
.edit(id: selectedTodo.id, description: textEditingController.text);
}
}
}
这种方法有五个显著的优点
- 易于维护
- 可读性增强
- 编写单元测试代码时的好处
- 提高工作流程效率
- 最小化协作过程中可能出现的错误
有关更详细的信息,请参阅我的博客文章 “使用 Mixin Class 组织 Flutter Riverpod 中的“全局”Providers”



