Asynchronous 在flatter中创建异步验证程序
我有一个异步函数,其中接受验证器的值作为参数:Asynchronous 在flatter中创建异步验证程序,asynchronous,dart,flutter,Asynchronous,Dart,Flutter,我有一个异步函数,其中接受验证器的值作为参数: validatePhone(number) { bool _isValid; Requests.get("http://apilayer.net/api/validate?value=$number", json: true) .then((val) { if (val['valid']) { // setState(() { <- also tried setting state here
validatePhone(number) {
bool _isValid;
Requests.get("http://apilayer.net/api/validate?value=$number", json: true)
.then((val) {
if (val['valid']) {
// setState(() { <- also tried setting state here
_isValid = true;
// });
} else {
// setState(() {
_isValid = false;
// });
}
});
return _isValid;
}
但它不起作用,它总是返回
null
或validatePhone
中设置的初始值。你知道我该怎么做吗 正如评论中所说,异步验证器不可能像预期的那样是一个字符串,而不是一个“未来”
然而,代码中有很多地方是错误的。首先,validatePhone
在设置\u isValid
之前返回,这就是为什么会得到一个null
值,因为它从未设置为任何值。您的请求在validatePhone
返回后完成,此时设置\u isValid
无效
让我们尝试修复validatePhone:
Future<bool> validatePhone(number) async {
bool _isValid;
final val = await Requests.get(
"http://apilayer.net/api/validate?value=$number",
json: true);
if (val['valid']) {
// setState(() {
_isValid = true;
// });
} else {
// setState(() {
_isValid = false;
// });
}
return _isValid;
}
您需要有一个表单密钥:
final _formKey = GlobalKey<FormState>();
我不是100%确定这是否有效,但值得一试 请检查,它支持异步验证器,除了提供其他优势外,您还可以设置解盎司时间
您可以在不使用FormBloc
的情况下使用TextFieldBloc
,但如果在FormBloc
中使用,它的功能会更强大
。。。
_phoneFieldBloc=TextFieldBloc(
asyncValidatorDebounceTime:持续时间(毫秒:300),
异步验证程序:[[u validatePhone],
);
...
。。。
TextFieldBlocBuilder(
textFieldBloc:_phoneFieldBloc,
suffixButton:suffixButton.CircularIndicator当正在进行异步验证时,
装饰:输入装饰(标签文本:“电话号码”),
键盘类型:TextInputType.phone,
),
...
示例#1-无FormBloc
导入'dart:async';
进口“包装:颤振/材料.省道”;
导入“包:form_bloc/form_bloc.dart”;
导入“包装:颤振形式集团/颤振形式集团.dart”;
void main()=>runApp(MaterialApp(主页:主屏幕());
类主屏幕扩展StatefulWidget{
主屏幕({Key}):超级(Key:Key);
_HomeScreenState createState()=>\u HomeScreenState();
}
类_homescrenstate扩展状态{
TextFieldBloc\u phoneFieldBloc;
StreamSubscription _textFieldBlocSubscription;
@凌驾
void initState(){
super.initState();
_phoneFieldBloc=TextFieldBloc(
asyncValidatorDebounceTime:持续时间(毫秒:300),
异步验证程序:[[u validatePhone],
);
_textFieldBlocSubscription=\u phoneFieldBloc.state.listen((状态){
if(state.isValid){
//当具有有效值时,打印_textFieldBloc的值
打印(状态值);
}
});
}
@凌驾
无效处置(){
_dispose();
_textFieldBlocSubscription.cancel();
super.dispose();
}
Future\u validatePhone(字符串编号)异步{
//假电话异步验证器
等待未来。延迟(持续时间(毫秒:200));
如果(number.length>4&&number.length<9){
返回“您的电话号码无效”;
}
返回null;
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
子项:TextFieldBlocBuilder(
textFieldBloc:_phoneFieldBloc,
suffixButton:suffixButton.CircularIndicator当正在进行异步验证时,
装饰:输入装饰(标签文本:“电话号码”),
键盘类型:TextInputType.phone,
),
),
);
}
}
示例#2-使用FormBloc
导入“包装:颤振/材料.省道”;
导入“包:form_bloc/form_bloc.dart”;
导入“包装:颤振形式集团/颤振形式集团.dart”;
void main()=>runApp(MaterialApp(主页:主屏幕());
类SimpleFormBloc扩展了FormBloc{
final phoneField=TextFieldBloc(
asyncValidatorDebounceTime:持续时间(毫秒:600),
);
最终emailField=TextFieldBloc(
验证人:[validators.email],
asyncValidatorDebounceTime:持续时间(毫秒:300),
);
@凌驾
List get fieldBlocs=>[phoneField,emailField];
SimpleFormBloc(){
addAsyncValidators([[u isValidPhone]);
addAsyncValidators([\u isEmailAvailable]);
}
Future _isValidPhone(字符串编号)异步{
//假电话异步验证器
等待未来。延迟(持续时间(毫秒:200));
如果(number.length>4&&number.length<9){
返回“您的电话号码无效”;
}
返回null;
}
未来的isEmailAvailable(字符串电子邮件)异步{
//假电子邮件异步验证程序
等待未来。延迟(持续时间(毫秒:200));
如果(电子邮件=='name@domain.com') {
返回“该电子邮件已被接收。请尝试另一封邮件”;
}否则{
返回null;
}
}
@凌驾
流提交()异步*{
//形式逻辑。。。
试一试{
//获取字段值:
打印(phoneField.value);
打印(emailField.value);
等待未来。延迟(持续时间(秒:2));
屈服currentState.toSuccess();
}捕获(e){
屈服电流状态(
'假错误,请继续测试异步验证。');
}
}
}
类主屏幕扩展StatefulWidget{
主屏幕({Key}):超级(Key:Key);
_HomeScreenState createState()=>\u HomeScreenState();
}
类_homescrenstate扩展状态{
SimpleFormBloc _SimpleFormBloc;
@凌驾
void initState(){
super.initState();
_simpleFormBloc=simpleFormBloc();
}
@凌驾
无效处置(){
_simpleFormBloc.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:FormBlocListener(
formBloc:_simpleFormBloc,
提交:(上下文、状态){
//显示进度对话框
显示对话框(
上下文:上下文,
禁止:错误,
建筑商:()=>Willposcope(
onWillPop:()async=>false,
儿童:中心(
孩子:卡片(
子:容器(
宽度:80,
他
String lastValidatedNumber;
String lastRejectedNumber;
// this will be called upon user interaction or re-initiation as commented below
String validatePhone(String number) {
if (lastValidatedNumber == number) {
return null;
} else if (lastRejectedNumber == number) {
return "Phone number is invalid";
} else {
initiateAsyncPhoneValidation(number);
return "Validation in progress";
}
}
Future<void> initiateAsyncPhoneValidation(String number) async {
final val = await Requests.get(
"http://apilayer.net/api/validate?value=$number",
json: true);
if (val['valid']) {
lastValidatedNumber = number;
} else {
lastRejectedNumber = number;
}
_formKey.currentState.validate(); // this will re-initiate the validation
}
final _formKey = GlobalKey<FormState>();
child: Form(
key: _formKey,
autovalidate: true,
child: TextFormField(
validator: validatePhone
)
)
dependencies:
form_bloc: ^0.5.2
flutter_form_bloc: ^0.4.3
dependencies:
form_bloc: ^0.5.2
flutter_form_bloc: ^0.4.3