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

Flutter中如何构造指定格式JSON对象并发送至服务端

修复方案

现有代码核心错误

  • 状态变量作用域错误:你把newQuiz、输入框控制器、临时字段变量全部定义在build方法内,每次Widget触发重绘就会重新初始化所有变量,之前添加的题目自然会丢失。
  • 实例构造逻辑错误:添加题目时调用Quiz.fromJson(newQuestion.toJson()),传入的是单道题的JSON结构,没有questions数组字段,Quiz的fromJson方法判断json['questions']为null,不会添加任何题目,最终得到空数组。
  • 冗余的取值逻辑:不需要额外定义question/solucion1等变量通过onChanged赋值,TextEditingController本身就可以直接获取最新的输入内容,还能避免取值不同步的问题。

修正步骤

  1. 首先确认你的页面是StatefulWidget,将所有状态变量移到State类的成员位置,不要放在build方法内。
  2. 修改添加题目的逻辑:不要每次都新建Quiz实例,直接往已有的Quiz实例的questions数组中追加新的题目即可。
  3. 发送数据时直接调用Quiz实例的toJson()方法,就能直接得到你要求的JSON结构。

修正后核心代码

// 你的State类示例
class _CreateQuizPageState extends State<CreateQuizPage> {
  // 输入框控制器定义为State成员
  final _questionController = TextEditingController();
  final _optionAController = TextEditingController();
  final _optionBController = TextEditingController();
  final _optionCController = TextEditingController();
  final _answerController = TextEditingController();
  // 全局保存正在编辑的测验实例
  final Quiz _newQuiz = Quiz(questions: []);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("创建$subjectName的新测验"),
        backgroundColor: Colors.green[700],
      ),
      body: ChangeNotifierProvider(
        create: (_) => LoginFormProvider(),
        child: Builder(builder: (context) {
          final loginFormProvider = Provider.of<LoginFormProvider>(context, listen: true);
          return Container(
            color: Colors.grey[100],
            padding: const EdgeInsets.symmetric(horizontal: 20),
            child: Center(
              child: ConstrainedBox(
                constraints: const BoxConstraints(maxHeight: 450),
                child: Form(
                  key: loginFormProvider.formKey,
                  child: Column(
                    children: [
                      TextFormField(
                        controller: _questionController,
                        decoration: buildInputDecoration(
                          hint: '题目内容',
                          label: '题目',
                          icon: Icons.edit
                        ),
                      ),
                      const SizedBox(height: 10,),
                      TextFormField(
                        controller: _optionAController,
                        decoration: buildInputDecoration(
                          hint: '选项A',
                          label: '选项A',
                          icon: Icons.edit
                        ),
                      ),
                      const SizedBox(height: 10,),
                      TextFormField(
                        controller: _optionBController,
                        decoration: buildInputDecoration(
                          hint: '选项B',
                          label: '选项B',
                          icon: Icons.edit
                        ),
                      ),
                      const SizedBox(height: 10,),
                      TextFormField(
                        controller: _optionCController,
                        decoration: buildInputDecoration(
                          hint: '选项C',
                          label: '选项C',
                          icon: Icons.edit
                        ),
                      ),
                      const SizedBox(height: 10,),
                      TextFormField(
                        controller: _answerController,
                        cursorColor: Colors.green,
                        decoration: buildInputDecoration(
                          hint: '正确答案',
                          label: '答案',
                          icon: Icons.edit
                        ),
                      ),
                      const SizedBox(height: 15,),
                      Row(
                        children: [
                          CustomOutlinedButton(
                            onPressed: () async {
                              // _newQuiz.toJson() 就是符合要求的JSON结构,直接传入请求即可
                              await createQuiz(_newQuiz.toJson(), teacherid, subjectid);
                            },
                            text: "创建测验"
                          ),
                          const SizedBox(width: 20,),
                          CustomOutlinedButton(
                            onPressed: () {
                              // 构造单道题目实例
                              final newQuestion = Questions(
                                answer: _answerController.text,
                                question: _questionController.text,
                                solucion1: _optionAController.text,
                                solucion2: _optionBController.text,
                                solucion3: _optionCController.text
                              );
                              // 追加到已有测验的题目列表中
                              _newQuiz.questions.add(newQuestion);
                              // 清空输入框准备下一题录入
                              _questionController.clear();
                              _optionAController.clear();
                              _optionBController.clear();
                              _optionCController.clear();
                              _answerController.clear();
                            },
                            text: '添加题目'
                          ),
                        ]
                      )
                    ],
                  ),
                ),
              ),
            ),
          );
        })
      ),
    );
  }

  // 销毁时释放控制器资源
  @override
  void dispose() {
    _questionController.dispose();
    _optionAController.dispose();
    _optionBController.dispose();
    _optionCController.dispose();
    _answerController.dispose();
    super.dispose();
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 10:36:02