flutter - 带有嵌套自定义 FormFields 的 Flutter Form onSaved 执行顺序
问题描述
我有一个自定义的FormField<String>
MyFancyTextFormField ,它只是用一些额外的包装了一个 TextFormField 。
我想单独使用这个 FormField,但我也想在另一个 FormField 中使用它:TextList,它基本上是一个填充了 MyFancyTextFormFields 的列。
我想出了这个:
class FirstWidget extends StatefulWidget {
@override
State createState() => FirstWidgetState();
}
class FirstWidgetState extends State<FirstWidget> {
GlobalKey<FormState> _form = GlobalKey<FormState>();
List<String> initial = ['one', 'two', 'three'];
List<String> modified;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Form(
key: _form,
child: TextList(initialValue: initial, onSaved: (values) => print('TextList saved with: ${modified = values}')),
),
RaisedButton(
child: Text('Save'),
onPressed: () {
_form.currentState.save();
print('Initial value was: $initial, modified value is: $modified');
},
)
],
),
);
}
}
class TextList extends FormField<List<String>> {
TextList({List<String> initialValue, FormFieldSetter<List<String>> onSaved})
: super(
initialValue: initialValue,
onSaved: onSaved,
builder: (state) {
//Make a copy
List<String> _value = List.of(state.value);
//This just creates the list of MyFancyTextFormField
List<Widget> fields = _value
.asMap()
.map<int, Widget>((i, val) => MapEntry(
i,
MyFancyTextFormField(
initialValue: _value[i],
onSaved: (val) {
print('MyFancyTextFormField[$i] saved with $val');
state.didChange(_value..replaceRange(i, i + 1, [val]));
})))
.values
.toList();
return Column(
children: fields,
);
});
}
class MyFancyTextFormField extends FormField<String> {
MyFancyTextFormField({
String initialValue,
FormFieldSetter<String> onSaved,
}) : super(
initialValue: initialValue,
onSaved: (value) => onSaved(value),
builder: (state) => TextFormField(
initialValue: initialValue,
onSaved: onSaved,
));
}
问题在于,当我保存()表单状态时,框架将首先保存我的顶级 FormField TextList,然后再保存我的叶级 FormField MyFancyTextFormField。
这是我的输出:
I/flutter ( 615): TextList saved with: [one, two, three]
I/flutter ( 615): MyFancyTextFormField[0] saved with one
I/flutter ( 615): MyFancyTextFormField[0] saved with oneee
I/flutter ( 615): MyFancyTextFormField[1] saved with two
I/flutter ( 615): MyFancyTextFormField[1] saved with two
I/flutter ( 615): MyFancyTextFormField[2] saved with three
I/flutter ( 615): MyFancyTextFormField[2] saved with threeeeeeeeee
I/flutter ( 615): Initial value was: [one, two, three], modified value is: [one, two, three]
由于第一次执行 save() 后,我的 TextList 的状态已正确更新,如果我再次运行 save(),我将得到预期的输出:
I/flutter ( 615): TextList saved with: [oneee, two, threeeeeeeeee]
I/flutter ( 615): MyFancyTextFormField[0] saved with one
I/flutter ( 615): MyFancyTextFormField[0] saved with oneee
I/flutter ( 615): MyFancyTextFormField[1] saved with two
I/flutter ( 615): MyFancyTextFormField[1] saved with two
I/flutter ( 615): MyFancyTextFormField[2] saved with three
I/flutter ( 615): MyFancyTextFormField[2] saved with threeeeeeeeee
I/flutter ( 615): Initial value was: [one, two, three], modified value is: [oneee, two, threeeeeeeeee]
为什么 MyFancyTextFormField(s) 的 onSaved 被调用了两次?
有没有办法让我的预期结果比调用 state.save() 的次数比我的 FormField 的树高更好?
先感谢您。
解决方案
很晚的答案,但我认为这是因为在构建器中MyFancyTextFormField
扩展FormField
并返回了一个TextFormField
附加值。如果你MyFancyTextFormField
变成一个返回 a 的无状态小部件,TextFormField
你会得到你想要的:
class MyFancyTextFormField extends StatelessWidget {
final String initialValue;
final FormFieldSetter<String> onSaved;
MyFancyTextFormField({
this.initialValue,
this.onSaved,
}) ;
@override
Widget build(BuildContext context) {
return TextFormField(
initialValue: initialValue,
onSaved: this.onSaved);
}
}
推荐阅读
- reactjs - 反应:在 setState() 之后为不在我的页面上的组件调用渲染函数
- excel - AppleScript 和 Numbers:无法向单元格添加值
- google-sheets - 谷歌表格 | 按类型分组计数项目
- javascript - 如何在 Angular 中将动态数据添加到 IBM 碳表?
- java - 如何初始化反应堆 HttpClient 的基本身份验证标头?
- powerbi - 电源BI。两个表面上相等的计算量度实际上是不同的。为什么?
- blazor - 动态删除字段时字段验证呈现的 Blazor 问题
- angular - Angular RxJS 计时器的工作方式与预期不同
- matlab - 根据初始点的颜色值在 MATLAB 中为 voronoi 图着色
- vba - Outlook 约会未显示已添加的与会者