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

Flutter Cubit搜索状态回退异常问题排查求助

笔记搜索功能Cubit状态更新异常修复

问题现象

  • 输入“o”时,能正确过滤出包含“o”的笔记;
  • 输入“on”时,过滤结果正常;
  • 但回退到“o”时,Cubit的state变为“on”对应的过滤结果,无法基于原始全量数据重新过滤,导致丢失部分结果。

示例:

  • 原始全量笔记:["one","only","two","five"]
  • 输入“o”:过滤结果为["one","only","two"],此时Cubit state被替换为该结果;
  • 输入“on”:基于已过滤的state再过滤,得到["one","only"];
  • 回退到“o”:只能基于["one","only"]过滤,结果与该列表一致,丢失了原有的"two"。

问题根源

NoteCubit的searchNote方法每次emit过滤后的列表,直接覆盖了存储原始全量数据的state,导致后续搜索无法基于完整数据集重新过滤。

解决方案

在NoteCubit内部维护一个独立的全量笔记数据源,所有数据修改操作同步更新该数据源,搜索操作始终基于全量数据源进行过滤,仅emit过滤后的结果,不修改全量数据源。

修改后的NoteCubit代码

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:notecraft/data/models/note_model.dart';

class NoteCubit extends Cubit<List<Note>> {
  // 维护全量笔记数据源
  final List<Note> _allNotes = [];

  NoteCubit() : super([]);

  void addNote(Note note) {
    _allNotes.add(note);
    emit(List.from(_allNotes));
  }

  void emitAllNotes() {
    emit(List.from(_allNotes));
  }

  List<Note>? getAllNotes() {
    return List.from(_allNotes);
  }

  Note? getNote(int id) {
    return _allNotes.firstWhere((note) => note.id == id, orElse: () => Note());
  }

  void getOneNote(int id) {
    emit(_allNotes
        .where((parseNote) => parseNote.id == id)
        .map((parseNote) => parseNote)
        .toList());
  }

  void updateNote(Note note) {
    final index = _allNotes.indexWhere((n) => n.id == note.id);
    if (index != -1) {
      _allNotes[index] = note.copyWith(
        title: note.title,
        description: note.description,
        updated_at: '22-jan-2024',
      );
      emit(List.from(_allNotes));
    }
  }

  void restoreNote(Note note) {
    final index = _allNotes.indexWhere((n) => n.id == note.id);
    if (index != -1) {
      _allNotes[index] = note.copyWith(isDeleted: 0);
      emit(List.from(_allNotes));
    }
  }

  void deleteNote(int id) {
    _allNotes.removeWhere((note) => note.id == id);
    emit(List.from(_allNotes));
  }

  void searchNote(String query) {
    if (query.isEmpty) {
      emit(List.from(_allNotes));
      return;
    }

    List<Note> filteredNotes = _allNotes
        .where((note) =>
            note.title.toLowerCase().contains(query.toLowerCase()) ||
            note.description.toLowerCase().contains(query.toLowerCase()))
        .toList();

    emit(filteredNotes);
  }
}

说明

  • 新增_allNotes私有变量存储全量笔记,所有增删改操作都直接修改该变量,然后emit全量数据的副本;
  • searchNote方法始终基于_allNotes进行过滤,emit过滤后的结果,不会修改全量数据源;
  • 其他组件(SearchInput、NotesScreen)无需修改,它们监听的Cubit state会根据操作自动更新为全量或过滤后的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 04:55:35