flutter - 为 Flutter 中动态生成的 TextFormField 生成 TextEditingController
问题描述
我必须根据 API 返回的数组在小部件TextFormField
下生成。Form
生成这些字段后,可以在其中输入值。当用户单击提交按钮时,应将每个字段的值放入一个数组中以发布 API。
要发送到 API 的对象
{
"billerId" :"12341249",
"customerParams": [ // Each object in this array denotes input field's name and value
{
"name": "Consumer Number",
"value" : "43141"
},
{
"name": "Subdivision Code",
"value": "23"
}
]
}
下面是我StatefulWidget
循环 overfields
数组(来自 API)以生成字段的地方。我的问题是当我点击提交按钮时,打印语句会记录对象,类似于上面,但最后一个字段被推送了两次。
// All necessary imports
class AddCustomerDetails extends StatefulWidget {
final Biller biller;
const AddCustomerDetails({Key key, this.biller}) : super(key: key);
@override
_AddCustomerDetailsState createState() => _AddCustomerDetailsState();
}
class _AddCustomerDetailsState extends State<AddCustomerDetails> {
final _formKey = GlobalKey<FormState>();
List _customerInputFields;
var _submitObj;
@override
void initState() {
_customerInputFields = widget.biller.customerParameter;
_submitObj = {'billerId': widget.biller.id, 'customerParams': []}; // Initializing it here
super.initState();
}
Widget _generateForm(List fields) {
return Form(
key: _formKey,
child: Column(
children: [
...fields.map((field) {
return TextFormField(
validator: (value) => _validateField(value),
onChanged: (value) {
_submitObj['customerParams']
.add({'name': field['paramName'], 'value': value}); // I know this is wrong and will push object on every key press
},
);
}).toList(),
SizedBox(height: 16),
RaisedButton(
onPressed: () {
if (_formKey.currentState.validate()) {
print(_submitObj); // See Actual response in snippet below
}
},
child: Text('Submit'),
),
],
),
);
}
String _validateField(value) {
// ... Validate field if empty
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Padding(
padding: EdgeInsets.all(
AppMediaQuery(context).appHorizontalPadding(4),
),
child: _generateForm(_customerInputFields),
),
],
),
);
}
}
实际响应
I/flutter ( 8118): {billerId: JBVNL0000JHA01, customerParams: [{name: Consumer Number, value: 4}, {name: Consumer Number, value: 43}, {name: Consumer Number, value: 431}, {name: Consumer Number, value: 4314}, {name: Consumer Number, value: 43141}, {name: Subdivision Code, value: 2}, {name: Subdivision Code, value: 23}]}
我不希望每次按键时它都会推动对象。 如何做到这一点?当然,我可以添加谴责,但这并不能解决问题。
解决方案
您可以使用地图而不是列表来收集值吗?
void initState() {
_customerInputFields = widget.biller.customerParameter;
/// Initialize `customerParams` as a map here
_submitObj = {'billerId': widget.biller.id, 'customerParams': {}};
super.initState();
}
...
return TextFormField(
validator: (value) => _validateField(value),
onChanged: (value) {
/// Add/Update the field subscript and value here
_submitObj['customerParams'][field['paramName']] = value;
},
);```
推荐阅读
- php - 在 WooCommerce 3 中显示空子类别
- c# - 如何在c#中显示组框内的所有项目
- jquery - 拖放后可拖动的 div 将失去其“向左浮动”属性
- php - 快速书籍创建客户 OAuth 2.0 令牌错误
- python - 如何使用 pybind11 从 virtualenv 运行 python 解释器?
- java - Eclipse:在内容辅助打开时更改选择所选建议的特定键/操作
- python - 如何将 n 个图像(jpg 格式)转换为 .p(pickle)格式?
- apache-spark - 火花流作业的纱线日志聚合
- spring - 在 Spring Boot 中,ModelAndView 对名为 model 的视图的引用为空
- laravel - Laravel 路由 [登录] 未在文件中定义