Flutter Bloc:更新后未调用 BlocBuilder,ListView 仍显示旧数据

Posted

技术标签:

【中文标题】Flutter Bloc:更新后未调用 BlocBuilder,ListView 仍显示旧数据【英文标题】:Flutter Bloc: BlocBuilder not getting called after an update, ListView still displays old data 【发布时间】:2019-08-25 11:50:24 【问题描述】:

我正在使用 flutter_bloc 进行状态管理并解决了这个问题。更新并保存字段时,BlocBuilder 不会刷新页面。添加或删除时它工作正常。我不确定我在这里做错了什么。

即使我转到另一个屏幕并返回此屏幕,即使文件已更新,它仍会显示旧数据。

我花了 2 个多小时试图调试它,但无济于事。我尝试初始化updatedTodos = [],然后逐个添加每个待办事项,看看是否有什么作用,但这也不起作用。

如有任何帮助,我们将不胜感激。

TodosBloc.dart:

Stream<TodosState> _mapUpdateTodoToState(
    TodosLoaded currentState,
    UpdateTodo event,
  ) async*      
        if (currentState is TodosLoaded) 
        final index = currentState.Todos
            .indexWhere((todo) => event.todo.id == todo.id);
        final List<TodoModel> updatedTodos =
            List.from(currentState.todos)
              ..removeAt(index)
              ..insert(index, event.todo);

        yield TodosLoaded(updatedTodos);
        _saveTodos(updatedTodos);
      
  

tod​​os_screen.dart:

...
Widget build(BuildContext context) 
    return BlocBuilder(
      bloc: _todosBloc,
      builder: (BuildContext context, TodosState state) 
        List<TodoModel> todos = const [];
        String _strings = "";
        if (state is TodosLoaded) 
          todos = state.todos;
        
        return Expanded(
          child: ListView.builder(
            itemCount: todos.length,
            itemBuilder: (BuildContext ctnx, int index) 
              return Dismissible(
                key: Key(todo.toString()),
                child: DetailCard(
                  todo: todos[index],
                ),
              );
            ,
          ),
        );
...

我期待 BlocBuilder 何时被调用并刷新 ListView。

【问题讨论】:

【参考方案1】:

在github 上的 Felix Angelov 的帮助下,我得以解决此问题。 问题是我正在扩展 Equatable 但没有将道具传递给 TodoModel 类中的超类。我必须用 super([]) 更新 TodoModel 的构造函数。

【讨论】:

我遇到了完全相同的问题,但我没有使用 Equatable 扩展我的模型类。我不知道如何解决这个问题。我真的觉得我“正确”地使用了flutter_bloc。似乎是这个特定库的设计缺陷。【参考方案2】:

这是我解决问题的方法,即使它不是最好的解决方案,但我会分享它,当你在另一个屏幕上你应该显示数据或其他东西时,按下后退按钮调用如下图处理

 @override
 void initState() 
   super.initState();
   print("id" + widget.teamID);
   BlocProvider.of<FootBallCubit>(context).getCurrentTeamInfo(widget.teamID);
 

 // what i noticed upon closing this instance of screen , it deletes old data
 @override
 void dispose() 
   super.dispose();
   Navigator.pop(context);
 

【讨论】:

以上是关于Flutter Bloc:更新后未调用 BlocBuilder,ListView 仍显示旧数据的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Bloc A 在 Bloc B 中添加流,但此流不会通过 StreamBuilder 在 UI 中呈现

Flutter bloc:更新状态不会重新调用 BlocBuilder

Flutter Bloc - Flutter Bloc 状态未更新

Flutter Bloc 状态更改未使用 get_it 更新 UI

Flutter BloC 模式:基于另一个 BloC 的流更新 BloC 流

Flutter_bloc 从没有 UI 事件的 firestore 获取更新的数据