干净的 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);  
    }  
  }  
}

这种方法有五个显著的优点

  1. 易于维护
  2. 可读性增强
  3. 编写单元测试代码时的好处
  4. 提高工作流程效率
  5. 最小化协作过程中可能出现的错误

有关更详细的信息,请参阅我的博客文章 “使用 Mixin Class 组织 Flutter Riverpod 中的“全局”Providers”

GitHub

查看 Github