通过不同的教程和资源,我试图在 Flutter 应用程序中获得动态表单,但我的用例看起来很高级,但我感觉很糟糕。
我的工作: 创建一个只有固定字符串和整数的反应形式。 我的表格供参考:
final form = fb.group({
'name': ['', Validators.required,],
'category': ['', Validators.required,],
'instructions': ['',],
'unit': [0, Validators.required,],
});
和:
@override
Widget build(BuildContext context) {
...
ReactiveForm(
formGroup: this.form,
child: Column(
children: <Widget>[
ReactiveTextField(
formControlName: 'name',
validationMessages: (control) => {
ValidationMessage.required:
'The name must not be empty',
},
...
),
],
),
我试图实现但没有成功的目标: 嵌入另一个对象。目标是允许用户根据需要动态添加步骤。所以我采用了 Array< Step > 方式,但即使使用简单的字符串列表,我也不知道如何让它工作...... 它应该适用于:
final form = fb.group({
...
'steps': fb.array([
'step 1',
'step 2',
]),
});
然后在表单中添加一个新步骤:
void _addStep(){
final array = form.control('steps') as FormArray<String>;
array.add(
FormControl<String>(value: 'next step'),
);
}
问题是,我不知道如何为此创建小部件,而且我找不到包含数组的示例。
我想我应该将 ReactiveFormArray() 添加到我的构建函数中,但我不知道如何构建应该是带有 ReactiveTextField 动态列表的单个小部件的东西(或者只是 TextFormField ,无论如何):
ReactiveFormArray(
formArrayName: 'steps',
builder: (BuildContext context, FormArray<dynamic> array, Widget child) {
**??**
},
),
我尝试了很多方法并使用reactive_forms 获得了最好的结果,遵循https://pub.dev/packages/reactive_forms,但如果您有更好的解决方案,我很乐意。
希望有人能帮助我。
答案 0 :(得分:0)
使用 FormGroup 代替 fb.group 并将 [] 转换为 FormControl。
import 'package:flutter/material.dart';
import 'package:reactive_forms/reactive_forms.dart';
void main() {
runApp(Example());
}
class Example extends StatefulWidget {
@override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
final steps = [
'step1',
'step2',
];
final form = FormGroup({
// 'name': FormControl<String>(validators: [Validators.required,]),
// 'category': FormControl<String>(validators: [Validators.required,]),
// 'instructions': FormControl<String>(),
// 'unit': FormControl<int>(validators: [Validators.required,]),
'steps': FormArray<String>([]),
});
FormArray<String> get selectedSteps => form.control('steps') as FormArray;
@override
void initState() {
selectedSteps.addAll(
steps.map((step) => FormControl<String>(value: '')).toList(),
);
super.initState();
}
Widget _buildStepListItem(step) {
return ReactiveTextField(
formControlName: this.steps.indexOf(step).toString(),
decoration: InputDecoration(
labelText: step,
),
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Steps',
home: Scaffold(
body: ReactiveForm(
formGroup: this.form,
child: Column(
children: [
ReactiveFormArray<String>(
formArrayName: 'steps',
builder: (context, formArray, child) => Column(
children: this.steps.map(_buildStepListItem).toList(),
),
),
ReactiveFormConsumer(
builder: (context, form, child) {
return RaisedButton(
child: Text('Send'),
onPressed: form.valid
? () {
print(this.selectedSteps.rawValue);
}
: null,
);
},
),
],
),
),
),
);
}
}