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