我正在寻找一个示例,如何在GetX的最佳实践中处理表单和验证? 有什么好的例子吗?或者有人可以给我一个例子,说明我们如何做到最好?
答案 0 :(得分:4)
这里有一个示例,说明如何使用 GetX 的 observable 动态更新表单字段和提交按钮。
我不声称这是最佳做法。我相信有更好的方法来完成同样的事情。但是尝试使用 GetX 来执行验证很有趣。
根据 Observable 值变化重建的两个感兴趣的小部件:
errorText
更改并将重建此小部件onChanged: fx.usernameChanged
不会导致重建。这会在表单字段输入更改时调用控制器 usernameChanged(String val)
中的函数。username
observable。onChanged: (val) => fx.username.value = val
onPressed
函数可以在 null
和函数之间切换null
禁用按钮(Flutter 中唯一的方法)class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
FormX fx = Get.put(FormX()); // controller
return Scaffold(
appBar: AppBar(
title: Text('Form Validation'),
),
body: SafeArea(
child: Container(
alignment: Alignment.center,
margin: EdgeInsets.symmetric(horizontal: 5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Obx(
() {
print('rebuild TextFormField ${fx.errorText.value}');
return TextFormField(
onChanged: fx.usernameChanged, // controller func
decoration: InputDecoration(
labelText: 'Username',
errorText: fx.errorText.value // obs
)
);
},
),
Obx(
() => RaisedButton(
child: Text('Submit'),
onPressed: fx.submitFunc.value, // obs
),
)
],
),
),
),
);
}
}
解释/分解如下
class FormX extends GetxController {
RxString username = ''.obs;
RxString errorText = RxString(null);
Rx<Function> submitFunc = Rx<Function>(null);
@override
void onInit() {
super.onInit();
debounce(username, validations, time: Duration(milliseconds: 500));
}
void validations(String val) async {
errorText.value = null; // reset validation errors to nothing
submitFunc.value = null; // disable submit while validating
if (val.isNotEmpty) {
if (lengthOK(val) && await available(val)) {
print('All validations passed, enable submit btn...');
submitFunc.value = submitFunction();
errorText.value = null;
}
}
}
bool lengthOK(String val, {int minLen = 5}) {
if (val.length < minLen) {
errorText.value = 'min. 5 chars';
return false;
}
return true;
}
Future<bool> available(String val) async {
print('Query availability of: $val');
await Future.delayed(
Duration(seconds: 1),
() => print('Available query returned')
);
if (val == "Sylvester") {
errorText.value = 'Name Taken';
return false;
}
return true;
}
void usernameChanged(String val) {
username.value = val;
}
Future<bool> Function() submitFunction() {
return () async {
print('Make database call to create ${username.value} account');
await Future.delayed(Duration(seconds: 1), () => print('User account created'));
return true;
};
}
}
从三个 observable 开始......
RxString username = ''.obs;
RxString errorText = RxString(null);
Rx<Function> submitFunc = Rx<Function>(null);
username
将保存最后输入到 TextFormField 中的任何内容。
errorText
使用 null
初始值实例化,因此用户名字段不是“无效”的开始。如果 not null(即使是空字符串),TextFormField 将呈现红色以表示无效输入。当字段中存在无效输入时,我们将显示错误消息。 (示例中的 min. 5 chars
:)
submitFunc
是一个持有提交按钮函数或 null
的 observable,因为 Dart 中的函数实际上是对象,这很好。 null
值初始分配将禁用按钮。
debounce
工作线程在更改 validations
可观察端 500 毫秒后调用 username
函数。
validations
将接收 username.value
作为其参数。
在 validations
函数中,我们放置了我们想要运行的任何类型的验证:最小长度、坏字符、已取的名字、由于童年欺凌而导致我们个人不喜欢的名字等。
为了增加真实感,available()
函数为 async
。通常,这会查询数据库以检查用户名的可用性,因此在此示例中,在返回此验证检查之前有一个假的 1 秒延迟。
submitFunction()
返回一个函数,当我们对表单具有有效输入感到满意并允许用户继续时,该函数将替换 submitFunc
observable 中的空值。
更现实一点,我们可能会。期待提交按钮函数的一些返回值,所以我们可以让按钮函数返回一个future bool:
Future<bool> Function() submitFunction() {
return () async {
print('Make database call to create ${username.value} account');
await Future.delayed(Duration(seconds: 1), () => print('User account created'));
return true;
};
}
答案 1 :(得分:1)
在这里看看
class LoginController extends GetxController{
TextEditingController email = TextEditingController();
TextEditingController password = TextEditingController();
void doLogin() {
if (email.text.isEmpty) {
errorSnackbar(msg: 'Enter Email Address');
} else if (password.text.isEmpty) {
errorSnackbar(msg: 'Enter Password');
} else if (password.text.length < 6) {
errorSnackbar(msg: "Password must be 6 digit");
} else {
// requestLogin();
}
}
void errorSnackbar({@required String msg}) {
return Get.snackbar(
'$msg',
"Error !",
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.red[200],
colorText: Colors.white
);
}
}
答案 2 :(得分:0)
GetX并不能解决所有问题,但是它具有一些实用程序方法可以帮助您实现所需的目标。例如,您可以将validator
和SnackBar
一起使用进行最终检查。这是一个代码段,可以帮助您了解基础知识。
TextFormField(
controller: emailController,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if (!GetUtils.isEmail(value))
return "Email is not valid";
else
return null;
},
),
GetUtils
几乎没有用于快速验证的便捷方法,您将不得不探索每种方法以查看其是否适合您的需求。