【问题标题】:Flutter - Why formKey.currentState.reset doesn't actually clear fields?Flutter - 为什么 formKey.currentState.reset 实际上并没有清除字段?
【发布时间】:2020-07-29 04:01:04
【问题描述】:

我要做的是在取消表单提交后清除条目。我正在尝试使用 _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();
                      }
                    },
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: android firebase flutter dart


    【解决方案1】:

    _formKey.currentState.reset() 将作为此表单后代的每个 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

    【讨论】:

    • 感谢您的回复,但表格仍然无法清理。我认为是带有 widget.user.weight / widget.user.name 的东西,它保存了输入,但我还没有弄清楚如何修复
    • 你在控制器内部初始化了吗? TextEditingController weightController = TextEditingController(text: widget.user.weight);
    • 是的,我做到了。我还在#Edit 1 上添加了新代码,你能检查一下吗?清理 onPressed 内部的控制器不起作用,但如果我将 widget.user.weight 放入一个空字符串,它就可以工作。虽然功能齐全,但我不知道逐个字段清理是否正确
    猜你喜欢
    • 2017-08-29
    • 1970-01-01
    • 2017-03-15
    • 2011-06-20
    • 1970-01-01
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 2017-07-30
    相关资源
    最近更新 更多