首页 > 解决方案 > Flutter - 为什么 formKey.currentState.reset 实际上并没有清除字段?

问题描述

我想要做的是在取消表单提交后清除条目。我正在尝试使用_formKey.currentState.reset()但这些字段没有被清理。我应该有一种逐场清洁的方法吗?下面我将使用用户名和权重字段显示我的代码,但我决定不放入代码中的其他字段(DropdownButton 和 Radio)以免太长:

class UserDetailForm extends StatefulWidget {
  final User user;
  const UserDetailForm(this.user);

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

class _UserDetailFormState extends State<UserDetailForm> {
  final UserController controller = UserController();
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
        child: Form(
          key: _formKey,
          autovalidate: true,
          child: Column(
            children: <Widget>[
              TextFormField(
                  initialValue: widget.user.name,
                  decoration: const InputDecoration(labelText: 'Name *'),
                  validator: (value) {
                    if (value.isEmpty) {
                      return 'Insert your name';
                    }
                    return null;
                  },
                  onChanged: (value) {
                    setState(() => widget.user.name = value);
                  }),
             
              TextFormField(
                  initialValue: widget.user.weight,
                  decoration: const InputDecoration(
                    labelText: 'Weight',
                  ),
                  onChanged: (value) {
                    setState(() => widget.user.weight = value);
                  }),

              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  MaterialButton(
                    child: Text("Cancel"),
                      onPressed: () {
                        _formKey.currentState.reset(); //NOT WORKING, SHOULD CLEAN THE FORM 
                        Navigator.of(context).pop();
                      },
                      ),
                  MaterialButton(
                    child: Text("Save"),
                      onPressed: () async {
                        if (_formKey.currentState.validate()) {
                          controller.updateUser(widget.user);
                          Navigator.of(context).pop();
                        }
                      },
                      ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

#Edit 1 - 使用TextEditingController(仅用于重量)问题仍然存在,取消表单提交后的条目没有被清理

class UserDetailForm extends StatefulWidget {
  final User user;
  const UserDetailForm(this.user);

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

class _UserDetailFormState extends State<UserDetailForm> {
  final UserController controller = UserController();
  final _formKey = GlobalKey<FormState>();
  TextEditingController weightController;

  initState() {
    weightController = TextEditingController(text: widget.user.weight);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
        child: Form(
          key: _formKey,
          autovalidate: true,
          child: Column(
            children: <Widget>[
              TextFormField(
                  initialValue: widget.user.name,
                  decoration: const InputDecoration(labelText: 'Name *'),
                  validator: (value) {
                    if (value.isEmpty) {
                      return 'Insert your name';
                    }
                    return null;
                  },
                  onChanged: (value) {
                    setState(() => widget.user.name = value);
                  }),

              TextFormField(
                controller: weightController,
                  decoration: const InputDecoration(
                    labelText: 'Weight',
                  ),
                  onChanged: (value) {
                    setState(() => widget.user.weight = value);
                  }),

              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  MaterialButton(
                    child: Text("Cancel"),
                    onPressed: () {
                      _formKey.currentState.reset();
                      weightController.text = "";
                      Navigator.of(context).pop();
                    },
                  ),
                  MaterialButton(
                    child: Text("Save"),
                    onPressed: () async {
                      if (_formKey.currentState.validate()) {
                        controller.updateUser(widget.user);
                        Navigator.of(context).pop();
                      }
                    },
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

标签: androidfirebaseflutterdart

解决方案


_formKey.currentState.reset()将作为此 Form 的后代的每个 FormField 重置为其FormField.initialValue,这就是您的代码中发生的事情。单击取消时,初始值仍在屏幕中。要解决这个问题,您需要使用TextEditingController. 所以首先初始化控制器:

  TextEditingController weightController = TextEditingController(text: "test");
  TextEditingController nameController   = TextEditingController(text: "test1");

并给每个控制器一个初始值(例如:测试)。然后绑定每个controllerfield

         TextFormField(
                controller : emailController,
                  decoration: const InputDecoration(labelText: 'Name *'),
                  validator: (value) {
                    if (value.isEmpty) {
                      return 'Insert your name';
                    }
                    return null;
                  }),
             
              TextFormField(
                controller: nameController,
                  decoration: const InputDecoration(
                    labelText: 'Weight',
                  )),

删除该initialValue属性,因为您在创建控制器时已经在初始化该字段。最后下onPressed()

                      onPressed: () {
                        _formKey.currentState.reset();
                        nameController.text = "";
                        emailController.text = "";
                       
                      },

将初始测试的值更改为空string


推荐阅读