flutter - 颤振中的异步验证仍然存在问题
问题描述
我喜欢检查我后端的数据库中是否已经存在电子邮件。因此,我尝试使用在异步调用返回后应该更改的状态变量。我找到了以下包含已接受答案的线程。
Flutter - TextFormField 的异步验证器
我尝试了这些答案以及一些变化,但它仍然对我不起作用。我只是模拟后端调用。打印设置 _emailExist 为 true,但我没有看到任何错误。如果我单击该按钮两次,则错误消息将正确显示。
import 'package:flutter/material.dart';
class LoginPage extends StatefulWidget {
LoginPage({Key key}) : super(key: key);
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final GlobalKey<FormState> _loginFormKey = GlobalKey<FormState>();
bool _emailExist = false;
@override
initState() {
super.initState();
}
checkEmail(String name) {
// Simulare async call
Future.delayed(Duration(seconds: 2)).then((val) {
setState(() {
_emailExist = true;
});
print(_emailExist);
});
return _emailExist;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Test"),
),
body: Container(
child: SingleChildScrollView(
child: Form(
key: _loginFormKey,
child: Column(
children: <Widget>[
TextFormField(
validator: (value) =>
checkEmail(value) ? "Email already taken" : null,
),
RaisedButton(
child: Text("Login"),
onPressed: () {
if (_loginFormKey.currentState.validate()) {}
},
)
],
),
))));
}
}
解决方案
TextFormField
需要一个同步函数作为验证器(这是一个执行某些任务然后返回其结果的普通函数)。
checkEmail
正是这个,一个同步函数。它设置了 a Future
,它将在两秒钟内设置_emailExist
为true
。但至关重要的是,它不会等待两秒钟。它立即返回_emailExist
(这是false
它第一次运行)的当前值。两秒钟后,您的Future
解析并设置_emailExist
为 true。这就是为什么当您第二次运行它时,它会按预期工作(_checkEmail
再次返回当前值,_emailExist
但这就是现在true
)。
解决此问题的一种方法是提供onChanged
和decoration
参数以达到相同的效果:
TextFormField(
onChanged: _handleChange,
decoration: InputDecoration(
errorText: _emailExist ? "Email already taken" : null,
),
),
现在,您可以在文本字段更改时进行异步后端调用,然后根据响应更新状态:
void _handleChange(String val) {
Future.delayed(Duration(seconds: 2)).then(() {
setState(() {
_emailExist = true;
});
print(_emailExist);
});
}
消除此功能是个好主意,这样您就不会在用户键入的每个字母中都发送请求!
推荐阅读
- reactjs - 将反应路由器与材料 ui 集成不起作用
- php - Laravel:创建工厂时违反完整性约束错误
- laravel - 如何显示 Laravel foreach 循环固定值?
- python - Kivy Buildozer 在 setup.py 中返回错误退出状态为 1
- clojurescript - ClojureScript 将 Javascript Map Iterator 转换为 seq
- javascript - 针对特定情况的 JS 正则表达式模式
- assembly - 当 D-cache 关闭时,使 D-cache 失效的目的是什么?
- algorithm - Big-Oh 表示法中最坏情况下的运行时间是多少
- javascript - 如何从flask接收数据到jquery?
- node.js - 无法访问 AWS EC2 实例 IP