为什么在 Flutter 中使用 provider 创建的多步骤表单中表单不保存它们的值?

问题描述 投票:0回答:2

我正在使用以下代码创建一个简单的多步骤问答表单,但表单似乎无法保存它们的值,当我转到第二个表单并返回时,

textFormField
值消失了。

“handler.dart”:

class FormCreateHandler extends StatefulWidget {
  const FormCreateHandler({super.key});
  static const routeName = '/-form-handler';

  @override
  State<FormCreateHandler> createState() =>
      _FormCreateHandlerState();
}

class _FormCreateHandlerState extends State<FormCreateHandler> {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Create>(
      create: (context) => Create(),
      child: Consumer<Create>(
        builder: (context, modal, child) {
          switch (modal.activeIndex) {
            case 0:
              return const FormQuestion1();
            case 1:
              return const FormQuestion2();
            default:
              return const FormQuestion1();
          }
        },
      ),
    );
  }
}

“表格问题1.dart”:

class FormQuestion1 extends StatefulWidget {
  const FormQuestion1({super.key});
  static const routeName = '/form-question1';

  @override
  State<FormQuestion1> createState() => _FormQuestion1State();
}

class _FormQuestion1State extends State<FormQuestion1> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Consumer<Create>(builder: (context, modal, child) {
      return Form(
        key: _formKey,
        child: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              TextFormField(
                decoration: const InputDecoration(
                  labelText: 'title',
                  border: OutlineInputBorder(),
                ),
                validator: (value) {
                  if (value!.isEmpty)
                    return 'Please enter the title of question';
                },
              ),
              TextFormField(
                minLines: 3,
                maxLines: 5,
                decoration: const InputDecoration(
                  labelText: 'description',
                  border: OutlineInputBorder(),
                ),
                validator: (value) {
                  if (value!.isEmpty || value.length < 30) {
                    return 'Description must be longer';
                  }
                },
              ),
              Padding(
                padding: EdgeInsets.all(10),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Expanded(
                      flex: 1,
                      child: ElevatedButton(
                        onPressed: () {
                          if (_formKey.currentState?.validate() ?? false) {
                            _formKey.currentState!.save();
                            modal.changeStep(2);
                          }
                        },
                        child: Text('Back'),
                      ),
                    ),
                    Expanded(
                      flex: 2,
                      child: ElevatedButton(
                        onPressed: null, 
                        child: Text('Submit'),
                      ),
                    ),
                    Expanded(
                      flex: 1,
                      child: ElevatedButton(
                        onPressed: () {
                          if (_formKey.currentState?.validate() ?? false) {
                            _formKey.currentState!.save();
                            modal.changeStep(4);
                          }
                        },
                        child: Text('Next'),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      );
    });
  }
}

“表格问题2.dart”

class FormQuestion2 extends StatefulWidget {
  const FormQuestion2({super.key});
  static const routeName = '/form-question2';

  @override
  State<FormQuestion2> createState() => _FormQuestion2State();
}

class _FormQuestion2State extends State<FormQuestion2> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Consumer<Create>(builder: (context, modal, child) {
      return Form(
        key: _formKey,
        child: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              TextFormField(
                decoration: const InputDecoration(
                  labelText: 'title',
                  border: OutlineInputBorder(),
                ),
                validator: (value) {
                  if (value!.isEmpty)
                    return 'Please enter the title of question';
                },
              ),
              TextFormField(
                minLines: 3,
                maxLines: 5,
                decoration: const InputDecoration(
                  labelText: 'description',
                  border: OutlineInputBorder(),
                ),
                validator: (value) {
                  if (value!.isEmpty || value.length < 30) {
                    return 'Description must be longer';
                  }
                },
              ),
              Padding(
                padding: EdgeInsets.all(10),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Expanded(
                      flex: 1,
                      child: ElevatedButton(
                        onPressed: () {
                          if (_formKey.currentState?.validate() ?? false) {
                            _formKey.currentState!.save();
                            modal.changeStep(2);
                          }
                        },
                        child: Text('Back'),
                      ),
                    ),
                    Expanded(
                      flex: 2,
                      child: ElevatedButton(
                        onPressed: null, 
                        child: Text('Submit'),
                      ),
                    ),
                    Expanded(
                      flex: 1,
                      child: ElevatedButton(
                        onPressed: () {
                          if (_formKey.currentState?.validate() ?? false) {
                            _formKey.currentState!.save();
                            modal.changeStep(4);
                          }
                        },
                        child: Text('Next'),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      );
    });
  }
}

如何修改此代码以保持表单的状态,直到用户按下提交按钮或关闭表单?

flutter forms provider state-management consumer
2个回答
1
投票

我第一次误解你的问题。您的问题是您正在更改消费者中的小部件。要解决此问题,您需要为消费者中的每个案例使用一个 GlobalKeys,例如:

      switch (modal.activeIndex) {
          case 0:
            return const BasicDetails(key: _basicKey);
          case 1:
            return const EducationDetails(key: _educationKey);

          default:
            return const BasicDetails(key: _basicKey);
        }

,或将数据存储在这些小部件之外(例如,您可以使用 BLoC)并在构建方法中初始化它们


0
投票

我认为这是由于 ListView 优化,您可以选择错误的方式:在 ListView 上使用 shrinkWrap: true,或者正确的方式:在 TextFormField 上使用 TextEditingController 或 initialValue 和 onChange

© www.soinside.com 2019 - 2024. All rights reserved.