TextFormField 验证器没有得到传递给它的值?
TextFormField validator is not getting a value passed to it?
我有一个正在开发的纸牌游戏计分应用程序,但我有一个似乎无法解决的错误。希望这里有人看到我的错误,或者可以指出潜在的修复方法。我有一个这样的输入,您可以在其中输入每个玩家本轮的分数。它只不过是一列行,其中包含一个 Text() 保存玩家姓名和一个 TextFormField() 到 enter/edit 分数。
Image showing the score input/edit dialog in the app
这是该行的代码:
child: TextFormField(
key: Key(p.name),
keyboardType: TextInputType.number,
initialValue: p.getRoundScore(round)?.toString() ?? '',
inputFormatters: [LengthLimitingTextInputFormatter(3)],
validator: (value) {
print('validate => ${p.name} : $value');
int score = int.tryParse(value);
return (score == null && value != null) ? "Must be a number" : null;
},
onChanged: (value) {
print('onChange => ${p.name} : $value');
setState(() {
int score = int.parse(value);
if (round == 9) score *= 2; // Queens round
if (round == 10) score *= 3; // Kings round
p.updateScore(round, score);
});
},
),
如果我输入分数,如 John =2、Hannah=1、Tias=2 和 Eric=0,然后单击保存按钮,我会从 print()s 中得到以下输出:
I/flutter (32660): onChange => John : 2
I/flutter (32660): onChange => Hannah : 1
I/flutter (32660): onChange => Tias : 2
I/flutter (32660): onChange => Eric : 0
I/flutter (32660): validate => John :
I/flutter (32660): validate => Hannah :
I/flutter (32660): validate => Tias :
I/flutter (32660): validate => Eric :
并且应用程序中的验证输出显示每个字段的错误:
Image showing the same score entry dialog with the validation errors
[编辑] 为完整性添加保存按钮的代码:
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
debugPrint(playerToJson(players));
Navigator.of(context).pop();
} }
我在这里错过了什么?我可以尝试删除 onChange 并转而使用 TextController 但这会增加复杂性,因为你可以有 3-6 个玩家,而且我必须有多个控制器才能工作......它们对我来说似乎也有点矫枉过正需要做的。
我不确定为什么传递给 validator() 的“值”总是空字符串,是我做错了什么吗?这是一个错误吗?有更好的方法吗?
也许您应该使用 Form-Widget 包装所有 TextFormFields,同时使用全局键来管理表单。另请参阅 flutter validation tutorial
中的步骤 1
好的,经过更多的挖掘后,似乎是 onChange 以某种方式导致了我的问题。尽管来自 Google 和其他人的所有示例都表明这是完全可以接受的,但当我注释掉 onChange 时,验证器会为每个字段获取传递给它的正确值。这实际上效果很好,因为我真的应该只在验证值后才将值保存到我的模型中,所以我只是将该逻辑移到验证器中。现在一切正常。
我有一个正在开发的纸牌游戏计分应用程序,但我有一个似乎无法解决的错误。希望这里有人看到我的错误,或者可以指出潜在的修复方法。我有一个这样的输入,您可以在其中输入每个玩家本轮的分数。它只不过是一列行,其中包含一个 Text() 保存玩家姓名和一个 TextFormField() 到 enter/edit 分数。
Image showing the score input/edit dialog in the app
这是该行的代码:
child: TextFormField(
key: Key(p.name),
keyboardType: TextInputType.number,
initialValue: p.getRoundScore(round)?.toString() ?? '',
inputFormatters: [LengthLimitingTextInputFormatter(3)],
validator: (value) {
print('validate => ${p.name} : $value');
int score = int.tryParse(value);
return (score == null && value != null) ? "Must be a number" : null;
},
onChanged: (value) {
print('onChange => ${p.name} : $value');
setState(() {
int score = int.parse(value);
if (round == 9) score *= 2; // Queens round
if (round == 10) score *= 3; // Kings round
p.updateScore(round, score);
});
},
),
如果我输入分数,如 John =2、Hannah=1、Tias=2 和 Eric=0,然后单击保存按钮,我会从 print()s 中得到以下输出:
I/flutter (32660): onChange => John : 2
I/flutter (32660): onChange => Hannah : 1
I/flutter (32660): onChange => Tias : 2
I/flutter (32660): onChange => Eric : 0
I/flutter (32660): validate => John :
I/flutter (32660): validate => Hannah :
I/flutter (32660): validate => Tias :
I/flutter (32660): validate => Eric :
并且应用程序中的验证输出显示每个字段的错误:
Image showing the same score entry dialog with the validation errors
[编辑] 为完整性添加保存按钮的代码:
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
debugPrint(playerToJson(players));
Navigator.of(context).pop();
} }
我在这里错过了什么?我可以尝试删除 onChange 并转而使用 TextController 但这会增加复杂性,因为你可以有 3-6 个玩家,而且我必须有多个控制器才能工作......它们对我来说似乎也有点矫枉过正需要做的。
我不确定为什么传递给 validator() 的“值”总是空字符串,是我做错了什么吗?这是一个错误吗?有更好的方法吗?
也许您应该使用 Form-Widget 包装所有 TextFormFields,同时使用全局键来管理表单。另请参阅 flutter validation tutorial
中的步骤 1好的,经过更多的挖掘后,似乎是 onChange 以某种方式导致了我的问题。尽管来自 Google 和其他人的所有示例都表明这是完全可以接受的,但当我注释掉 onChange 时,验证器会为每个字段获取传递给它的正确值。这实际上效果很好,因为我真的应该只在验证值后才将值保存到我的模型中,所以我只是将该逻辑移到验证器中。现在一切正常。