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

Flutter集成ASP.NET API时嵌套类List搜索UI不更新问题求助

问题分析与解决方案

核心问题

  1. 状态更新时机错误:setState仅包裹了Timer的创建逻辑,异步回调中对displaymodel的赋值不在setState范围内,导致UI无法感知数据变化。
  2. Bloc状态管理误用:既然采用Bloc框架,直接使用setState会破坏状态管理的统一性,应该通过Bloc的事件-状态流来更新数据。
  3. 空安全隐患:代码中使用rows!、id!强制解包,若数据存在空值会触发异常,同时可能导致过滤逻辑失效。

分步解决

方案1:临时修复setState版本(快速验证)

将setState移至Timer的回调内部,确保数据更新时触发UI重建:

void updateModel(String value) {
  if (_debounce?.isActive ?? false) _debounce?.cancel();
  
  _debounce = Timer(const Duration(milliseconds: 500), () {   
    setState(() {
      displaymodel = data.where((element) {
        // 先判断rows是否为空,避免空指针
        if (element.rows == null) return false;
        return element.rows!.any((row) {
          // 判断id是否为空,再执行匹配
          if (row.id == null) return false;
          return row.id!.toLowerCase().contains(value.toLowerCase());
        });
      }).toList();
    });
  });
}

方案2:适配Bloc状态管理(推荐)

既然使用Bloc,应该将过滤逻辑放到Bloc中,通过事件触发状态更新:

1. 定义搜索事件

class SearchListEvent extends Equatable {
  final String query;

  const SearchListEvent(this.query);

  @override
  List<Object?> get props => [query];
}

2. 在Bloc中处理过滤逻辑

class ListBloc extends Bloc<ListEvent, ListState> {
  final List<ListModel> originalData;
  List<ListModel> filteredData = [];

  ListBloc(this.originalData) : super(ListLoadedState(originalData)) {
    on<SearchListEvent>((event, emit) {
      final query = event.query.toLowerCase();
      if (query.isEmpty) {
        filteredData = List.from(originalData);
      } else {
        filteredData = originalData.where((element) {
          if (element.rows == null) return false;
          return element.rows!.any((row) {
            if (row.id == null) return false;
            return row.id!.toLowerCase().contains(query);
          });
        }).toList();
      }
      emit(ListLoadedState(filteredData));
    });
  }
}

3. UI层监听Bloc状态

// 在UI组件中
BlocBuilder<ListBloc, ListState>(
  builder: (context, state) {
    if (state is ListLoadedState) {
      return ListView.builder(
        itemCount: state.data.length,
        itemBuilder: (context, index) {
          // 构建列表项
          return ListTile(title: Text(state.data[index].drainageid ?? ''));
        },
      );
    }
    return const CircularProgressIndicator();
  },
)

// 搜索输入框回调
TextField(
  onChanged: (value) {
    context.read<ListBloc>().add(SearchListEvent(value));
  },
)

额外优化点

  • 类名遵循Dart规范:listmodel改为ListModel,Rows改为RowModel(避免和Flutter内置的Row组件冲突)。
  • 去掉冗余的fromJsonn方法,统一用fromJson即可。
  • 过滤逻辑中增加空值判断,避免强制解包带来的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 00:29:51