Flutter 如何在颤振中使用restful调用验证textformfield中的值?
我想检查表格中输入的邮政编码是否有效。我用它来验证 我想向用户显示,如下图所示,如果他们输入的邮政编码不正确Flutter 如何在颤振中使用restful调用验证textformfield中的值?,flutter,dart,Flutter,Dart,我想检查表格中输入的邮政编码是否有效。我用它来验证 我想向用户显示,如下图所示,如果他们输入的邮政编码不正确 Widget formUI(){ 返回新列( 儿童:[ 新TextFormField( 装饰:新输入装饰(hintText:“电子邮件ID”), 键盘类型:TextInputType.emailAddress, 最大长度:32, 验证程序:Validation.validateEmail, onSaved:(字符串val){ email=val; }), 新TextFormField(
Widget formUI(){
返回新列(
儿童:[
新TextFormField(
装饰:新输入装饰(hintText:“电子邮件ID”),
键盘类型:TextInputType.emailAddress,
最大长度:32,
验证程序:Validation.validateEmail,
onSaved:(字符串val){
email=val;
}),
新TextFormField(
装饰:新输入装饰(hintText:“密码”),
最大长度:32,
验证程序:Validation.validateName,
onSaved:(字符串val){
密码=val;
打印(“名称现在是$val中的$password”);
},
),
//我想验证邮政编码
新TextFormField(
装饰:新输入装饰(hintText:“邮政编码”),
最大长度:32,
验证程序:检查PostCode(),
onSaved:(字符串val){
邮政编码=val;
打印(“名称现在是$val中的$postcode”);
},
),
新尺寸盒子(高度:15.0),
新升起的按钮(
已按下:(){
如果(_sendToServer()){
_showSnackBar(“成功注册!”);
}
},
子项:新文本(“注册”),
),
],
);
}
我有下面的代码来调用API。我想在表格上显示错误响应,例如“无效邮政编码”
未来检查PostCode()异步{
最后答复=
等待http.get('https://api.postcodes.io/postcodes/$postcode');
如果(response.statusCode!=200){
var map=ErrorMessage.fromJson(json.decode(response.body));
postcodeValidator=map.error;
返回map.error;
}
返回null;
}
您在使用验证程序
属性时面临的问题是,如果postalcode不正确,您必须同步返回一个字符串
在您的情况下,这是不可能的,因为您需要等待网络呼叫完成。解决此问题的一个方法是将
textededitingcontroller
附加到TextFormField
每次输入值时,我都会向API发出网络请求。
(这并不理想,您可以在此处使用一个去盎司函数,以避免对API发送太多垃圾邮件)
只要所有字段无效,“提交”按钮就会被禁用
概念验证代码:
class PostcodeValidator extends StatefulWidget {
@override
_PostcodeValidatorState createState() => _PostcodeValidatorState();
}
class _PostcodeValidatorState extends State<PostcodeValidator> {
String email;
String password;
String postcode;
bool hasValidPostcode = false;
bool get canSubmitForm => hasValidPostcode;
String postcodeErrorMessage;
final TextEditingController _postcodeController = TextEditingController();
void checkPostalCode(String postcode) async {
final response = await http.get('https://api.postcodes.io/postcodes/$postcode');
if (response.statusCode != 200) {
setState(() {
hasValidPostcode = false;
postcodeErrorMessage = json.decode(response.body)["error"];
});
}
if (response.statusCode == 200) {
setState(() {
hasValidPostcode = true;
});
}
return null;
}
@override
void initState() {
super.initState();
_postcodeController.addListener(() {
final postcodeInput = _postcodeController.value.text;
if (postcodeInput.isNotEmpty) {
checkPostalCode(postcodeInput);
}
});
}
@override
Widget build(BuildContext context) => Column(
children: <Widget>[
TextFormField(
controller: _postcodeController,
decoration: InputDecoration(hintText: 'Postcode'),
maxLength: 32,
autovalidate: true,
validator: (_) => hasValidPostcode ? null : postcodeErrorMessage,
onSaved: (String val) {
postcode = val;
print("name is now $postcode from $val");
},
),
RaisedButton(
onPressed: canSubmitForm ? _sendToServer : null,
child: new Text('Sign up'),
),
],
);
void _sendToServer() {
print("Submitting");
}
}
class PostcodeValidator扩展StatefulWidget{
@凌驾
_PostcodeValidatorState createState()=>\u PostcodeValidatorState();
}
类_postcodevalidator状态扩展状态{
字符串电子邮件;
字符串密码;
字符串邮政编码;
bool hasValidPostcode=false;
bool get canSubmitForm=>hasValidPostcode;
字符串后编码错误消息;
最终文本编辑控制器_postcodeController=文本编辑控制器();
void checkPostalCode(字符串邮政编码)异步{
最终响应=等待http.get('https://api.postcodes.io/postcodes/$postcode');
如果(response.statusCode!=200){
设置状态(){
hasValidPostcode=false;
postcodeErrorMessage=json.decode(response.body)[“error”];
});
}
如果(response.statusCode==200){
设置状态(){
hasValidPostcode=true;
});
}
返回null;
}
@凌驾
void initState(){
super.initState();
_postcodeController.addListener((){
最终邮政编码输入=_postcodeController.value.text;
if(postcodeInput.isNotEmpty){
检查PostalCode(postcodeInput);
}
});
}
@凌驾
小部件构建(构建上下文)=>列(
儿童:[
TextFormField(
控制器:_postcodeController,
装饰:输入装饰(hintText:“邮政编码”),
最大长度:32,
自动验证:true,
验证程序:()=>hasValidPostcode?null:postcodeErrorMessage,
onSaved:(字符串val){
邮政编码=val;
打印(“名称现在是$val中的$postcode”);
},
),
升起的按钮(
onPressed:canSubmitForm?\u sendToServer:null,
子项:新文本(“注册”),
),
],
);
void_sendToServer(){
打印(“提交”);
}
}
您可以使用它,它支持异步验证器,并且您可以设置反Bounce时间以不向API发送垃圾邮件,此外还提供了其他优势
因此,当您在SignUpFormBloc
中创建TextFieldBloc
时,您可以设置去盎司时间:
class SignUpFormBloc扩展了FormBloc{
...
最终postcodeField=TextFieldBloc(
asyncValidatorDebounceTime:持续时间(毫秒:1000),
);
...
}
然后在构造函数中,您可以添加异步验证程序:
。。。
SignUpFormBloc(){
addAsyncValidators([[u isValidPostcode]);
}
...
如果键入时不希望自动验证,并且仅在提交表单时,可以在super
构造函数中将autoValitade
设置为false
:
...
SignUpFormBloc() : super(autoValidate: false) {
postcodeField.addAsyncValidators([_isValidPostcode]);
}
...
或者,如果您希望自动验证,并且仅在提交表单时检查异步验证程序,则可以检查以下答案:
这是一个可以运行的示例:
dependencies:
form_bloc: ^0.5.2
flutter_form_bloc: ^0.4.4
http: ^0.12.0+2
导入'dart:async';
导入“dart:convert”;
进口“包装:颤振/材料.省道”;
导入“包:form_bloc/form_bloc.dart”;
导入“包装:颤振形式集团/颤振形式集团.dart”;
将“package:http/http.dart”导入为http;
void main()=>runApp(MaterialApp(home:SignUpScreen());
类SignUpFormBloc扩展了FormBloc{
最终emailField=TextFieldBloc(
验证人:[validators.email],
);
最终passwordField=TextFieldBloc(
验证器:[validators.passwordMin6Chars],
);
最终postcodeField=TextFieldBloc(
asyncValidatorDebounceTime:持续时间(毫秒:500),
);
@凌驾
列表获取字段BL
...
SignUpFormBloc() : super(autoValidate: false) {
postcodeField.addAsyncValidators([_isValidPostcode]);
}
...
dependencies:
form_bloc: ^0.5.2
flutter_form_bloc: ^0.4.4
http: ^0.12.0+2