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

Flutter页面打开时无法触发Bloc事件加载列表数据如何解决

Flutter Bloc页面初始化自动请求数据修复方案

核心问题原因

你当前代码无法触发初始化事件的核心原因是Bloc的注册时序和事件触发顺序错了:

  • 你把BlocProvider写在当前组件的build方法里,而initState的执行时机早于build方法
  • 执行initState里的context.read<WorkOrderBloc>()时,WorkOrderBloc还没有被注册到当前组件的上下文里,自然触发事件没有任何响应

其他存在的问题

  • 你自己维护的workOrderList声明为late但没有初始值,接口请求完成前访问会抛出空安全异常
  • 独立的顶层方法_myListView无法直接访问State类里的私有变量workOrderList
  • 使用Bloc的情况下没必要手动调用setState存列表数据,直接从Bloc的State里取数据即可
  • Checkbox的选中状态写在build方法里,每次页面刷新都会重置为false,且setState的语法存在错误

修复后完整代码

class OrderListWidget extends StatefulWidget {
  const OrderListWidget({Key? key}) : super(key: key);

  @override
  _OrderListWidgetState createState() => _OrderListWidgetState();
}

class _OrderListWidgetState extends State<OrderListWidget> {
  // 存储列表选中状态,不需要存在Bloc里的话可以本地维护
  final List<bool> selectedList = [];

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      // 创建Bloc之后直接触发初始化请求事件,不需要依赖initState触发
      create: (context) => WorkOrderBloc(
          workOrderRepo: context.read<WorkOrderRepository>(),
          type: WorkOrderType.mt
      )..add(WorkOrderListing(orderType: WorkOrderType.mt)),
      child: BlocListener<WorkOrderBloc, WorkOrderState>(
        listener: (context, state) {
          final formStatus = state.formStatus;

          if (formStatus is FormSubmitting) {
            LoadingDialog.openLoadingDialog(context, 'Please Wait');
          } else {
            if (formStatus is! InitialFormStatus) {
              LoadingDialog.closeLoadingDialog(context);
            }
            if (formStatus is SubmissionFailed) {
              SnackbarWidget.show(context, formStatus.exception.toString(), Colors.red);
            }
            if (formStatus is SubmissionSuccess) {
              // 初始化选中状态列表
              selectedList.clear();
              selectedList.addAll(List.filled(state.workOrderList?.length ?? 0, false));
            }
          }
        },
        child: BlocBuilder<WorkOrderBloc, WorkOrderState>(
          builder: (context, state) {
            // 直接从BlocState里取列表,不用自己额外维护变量
            final workOrderList = state.workOrderList;
            // 处理不同状态的页面渲染
            if (state.formStatus is FormSubmitting) {
              return const Center(child: CircularProgressIndicator());
            }
            if (workOrderList == null || workOrderList.isEmpty) {
              return const Center(child: Text('暂无工单数据'));
            }
            return _myListView(context, workOrderList);
          },
        ),
      ),
    );
  }

  // 改成内部方法,把列表数据作为参数传入
  Widget _myListView(BuildContext context, List<WorkOrder> workOrderList) {
    return ListView.builder(
      itemCount: workOrderList.length,
      itemBuilder: (context, index) {
        return Card(
          child: CheckboxListTile(
            value: selectedList[index],
            onChanged: (value) {
              // 修正setState语法
              setState(() {
                selectedList[index] = value!;
              });
            },
            title: Text(workOrderList[index].Name),
          ),
        );
      },
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 19:09:02