You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Bloc Pattern根据用户ID分配对应的待办事项?

现有问题修正

  1. 你当前编写的findByID逻辑无效:element.id == element.id判断条件永远为真,筛选结果和原列表完全一致,没有筛选作用。
  2. 该方法不需要设置为异步:筛选操作是针对已经加载到内存的用户、待办列表执行,没有IO类耗时操作,同步执行即可完成。
  3. 不要把该逻辑放到导航层:数据关联属于业务逻辑,应该统一收敛在Bloc类中,保持逻辑分层清晰。

正确改造方案

步骤1:修改Bloc类逻辑

你已经在Bloc中加载了全量的用户和待办数据,只需要新增缓存存储全量待办,再提供根据用户ID筛选待办的方法即可,改造后代码如下:

class ApisBloc{
  final _repos = Repositary();
  final _usersFetcher = PublishSubject<List<Users>>();
  final _todoUsers = PublishSubject<List<UsersToDos>>();
  // 新增:缓存全量待办列表,用于后续筛选
  List<UsersToDos> _allTodosCache = [];

  Stream<List<Users>> get allUsers => _usersFetcher.stream;
  Stream<List<UsersToDos>> get allTodos => _todoUsers.stream;

  fetchUsers() async{
    List<Users> usersModels = await _repos.fetchUsers();
    _usersFetcher.sink.add(usersModels);
  }

  fetchTodos() async{
    List<UsersToDos> todo = await _repos.fetchTodosUsers();
    // 加载待办时更新本地缓存
    _allTodosCache = todo;
    _todoUsers.sink.add(todo);
  }

  dispose(){
    _usersFetcher.close();
    _todoUsers.close();
  }

  // 改造后的筛选方法:传入用户ID,返回对应用户的待办列表
  List<UsersToDos> findTodosByUserId(int userId){
    // 假设待办实体类中有关联用户的userId字段,和用户的id字段对应
    return _allTodosCache.where((todo) => todo.userId == userId).toList();
  }
}
final bloc = ApisBloc();

步骤2:UI层调用

在用户列表的点击事件中直接调用Bloc的筛选方法,拿到对应用户的待办后传递给待办页面即可,示例代码如下:

// 用户列表渲染的StreamBuilder示例
StreamBuilder<List<Users>>(
  stream: bloc.allUsers,
  builder: (context, snapshot) {
    if (!snapshot.hasData) return const CircularProgressIndicator();
    return ListView.builder(
      itemCount: snapshot.data!.length,
      itemBuilder: (context, index) {
        final user = snapshot.data![index];
        return ListTile(
          title: Text(user.name),
          onTap: () {
            // 点击用户时筛选对应待办
            final userTodos = bloc.findTodosByUserId(user.id);
            // 跳转到待办页面,传递筛选后的待办数据
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => UserTodoPage(todos: userTodos),
              ),
            );
          },
        );
      },
    );
  }
)

可选优化方案

如果你的待办数据会有实时更新的需求,可以在Bloc中新增专门的当前用户待办流,点击用户时自动推送筛选后的待办,待办页面直接监听流做响应式渲染即可:

// Bloc内新增代码
final _currentUserTodos = PublishSubject<List<UsersToDos>>();
Stream<List<UsersToDos>> get currentUserTodos => _currentUserTodos.stream;

void selectUser(int userId) {
  final filteredTodos = _allTodosCache.where((todo) => todo.userId == userId).toList();
  _currentUserTodos.sink.add(filteredTodos);
}

UI侧点击用户时调用bloc.selectUser(user.id),待办页面监听bloc.currentUserTodos流渲染列表即可。


内容的提问来源于stack exchange,提问作者user16357470

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 08:06:04