Flutter TextField编辑后值未更新 提交API仍为旧数据解决方案
问题根源
你当前代码的核心错误是在build方法内给TextField绑定controller时,使用controller: _name..text = '${data[0]['name']}'这种写法,会在**每一次Widget重建(build执行)**时,强制把输入框内容重置为接口拉取的初始值,你手动输入的所有修改都会被覆盖,因此提交时永远拿到初始旧值。
另外还有几个潜在问题:
- 没有做接口返回数据的空判断,接口请求未完成时
data为null,直接读取data[0]会触发空异常 - 没有在页面销毁时释放TextEditingController,会造成内存泄漏
- POST请求逻辑不规范,参数拼在url query中却设置body为null,不符合常规POST接口的传参约定,容易被后端拦截
修复方案
- 移除build方法内所有给controller.text赋值的逻辑,初始值仅在接口请求成功、拿到用户数据后赋值一次
- 增加空安全判断,避免接口未返回数据时的报错
- 补充controller的dispose释放逻辑
- 调整POST传参逻辑,将提交参数放到请求body中(和后端约定一致即可)
修正后的核心代码
1. 调整接口拉取后的初始值赋值逻辑
getData() async{ var res = await http.get(Uri.https('www.*******.com', '/index.php',{'act':'profile','UsrID': '${UsrID}'})); data = jsonDecode(res.body); // 仅在接口返回有效数据后 给输入框赋一次初始值 if(data != null && data.isNotEmpty){ _name.text = data[0]['name'] ?? ''; _email.text = data[0]['email'] ?? ''; _phone.text = data[0]['mobile'] ?? ''; } setState(() {}); }
2. 简化TextField绑定代码,移除build内的强制赋值
三个输入框都去掉级联的text赋值,直接绑定controller即可:
// 姓名输入框 TextField( controller: _name, keyboardType: TextInputType.text, obscureText: false, decoration: InputDecoration( hintText: 'Zeo Saldana', ), ) // 邮箱输入框 TextField( controller: _email, keyboardType: TextInputType.text, obscureText: false, decoration: InputDecoration( hintText: 'jakson@gmail.com', ), ) // 手机号输入框 TextField( controller: _phone, keyboardType: TextInputType.text, obscureText: false, decoration: InputDecoration( hintText: '+1 94526 12547', ), )
3. 补充controller释放逻辑
在State类中新增dispose回调:
@override void dispose() { _name.dispose(); _email.dispose(); _phone.dispose(); super.dispose(); }
4. 调整提交逻辑的传参方式
onPressed: () async{ final url = Uri.https('www.*******.net', '/index.php',{'act':'profileupdate'}); final response = await http.post( url, headers: {'Content-Type': 'application/json'}, // 提交参数放到请求body中 直接读取controller的实时值 body: jsonEncode({ 'name': _name.text, 'email': _email.text, 'phone': _phone.text, 'user': UsrID, }) ); // 下方响应处理逻辑保持原有逻辑即可 int statusCode = response.statusCode; Map<String, dynamic> responseBody = jsonDecode(response.body); var list = responseBody['error']; var stringList = list.join("\n"); print(stringList); var statusRes = responseBody['status']; var UserID = responseBody['usrid']; if(statusRes == 'success'){ print('success: '+statusRes); print(UserID); } else { print('error: '+statusRes); } print(responseBody); setState(() {}); }
改完之后输入框就不会再被强制重置,输入的内容可以正常被controller读取,提交时就能拿到最新的修改值。
内容的提问来源于stack exchange,提问作者RAF Algowid
相关产品推荐
相关产品推荐

