#forms #flutter #validation #flutter-getx #flutter-form-builder
#формы #флаттер #проверка #flutter-getx #flutter-конструктор форм
Вопрос:
Я ищу пример того, как наилучшим образом обрабатывать формы и валидацию с помощью getX? Есть ли какой-нибудь хороший пример этого или кто-нибудь может показать мне пример того, как мы лучше всего можем это сделать?
Комментарии:
1. вы можете увидеть расширение getx для vs code. В нем есть несколько фрагментов для getx, а также getx forms. marketplace.visualstudio.com /…
Ответ №1:
Вот пример того, как вы могли бы использовать наблюдаемые getX для динамического обновления полей формы и кнопки отправки.
Я не утверждаю, что это лучшая практика. Я уверен, что есть лучшие способы сделать то же самое. Но интересно поиграть с тем, как getX можно использовать для выполнения проверки.
Форма Obx
Два представляющих интерес виджета, которые перестраиваются на основе наблюдаемых изменений значений:
- TextFormField
errorText
Изменения InputDecoration и перестроят этот виджетonChanged: fx.usernameChanged
не вызывает перестроек. Это вызывает функцию в контроллереusernameChanged(String val)
при изменении ввода поля формы.- Он просто обновляет
username
наблюдаемое новым значением. - Может быть записано как:
onChanged: (val) => fx.username.value = val
- ElevatedButton (кнопка «Отправить»)
onPressed
функция может переключаться междуnull
и функциейnull
отключает кнопку (единственный способ сделать это в Flutter)- функция здесь активирует кнопку
class FormObxPage extends StatelessWidget {
const FormObxPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
FormX fx = Get.put(FormX()); // controller
return Scaffold(
appBar: AppBar(
title: const Text('Form Validation'),
),
body: SafeArea(
child: Container(
alignment: Alignment.center,
margin: const 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(
() => ElevatedButton(
child: const Text('Submit'),
onPressed: fx.submitFunc.value, // obs
),
)
],
),
),
),
);
}
}
Контроллер getX
Объяснение / разбивка ниже
class FormX extends GetxController {
RxString username = RxString('');
RxnString errorText = RxnString(null);
Rxn<Function()> submitFunc = Rxn<Function()>(null);
@override
void onInit() {
super.onInit();
debounce<String>(username, validations, time: const 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) amp;amp; 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(
const 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(const Duration(seconds: 1), () => print('User account created'));
return true;
};
}
}
Наблюдаемые
Начиная с трех наблюдаемых…
RxString username = RxString('');
RxnString errorText = RxnString(null);
Rxn<Function()> submitFunc = Rxn<Function()>(null);
username
будет содержать все, что было последним введенным в поле TextFormField.
errorText
создается экземпляр с null
начальным значением, поэтому поле имени пользователя изначально не является «недопустимым». Если значение не равно null (даже пустая строка), TextFormField будет отображаться красным цветом, что означает недопустимый ввод. Когда в поле вводится недопустимый ввод, мы показываем сообщение об ошибке. ( min. 5 chars
в примере:)
submitFunc
является наблюдаемым для удержания функции кнопки отправки или null
, поскольку функции в Dart на самом деле являются объектами, это нормально. Первоначальное null
присвоение значения отключит кнопку.
OnInit
debounce
Рабочий вызывает validations
функцию через 500 мс после внесения изменений в username
наблюдаемый конец.
validations
получит username.value
в качестве своего аргумента.
Проверки
Внутри validations
функции мы помещаем любые типы проверки, которые мы хотим выполнить: минимальная длина, плохие символы, имя, которое уже занято, имена, которые нам лично не нравятся из-за детских хулиганов и т. Д.
Для дополнительного реализма available()
функция async
. Обычно при этом запрашивается база данных для проверки доступности имени пользователя, поэтому в этом примере перед возвратом этой проверки проверки возникает ложная задержка в 1 секунду.
submitFunction()
возвращает функцию, которая заменит нулевое значение в submitFunc
observable, когда мы убедимся, что форма имеет допустимые входные данные, и мы разрешаем пользователю продолжить.
Мы бы попробовали быть немного более реалистичными. ожидайте некоторого возвращаемого значения от функции кнопки отправки, чтобы мы могли заставить функцию кнопки возвращать будущий 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;
};
}
Ответ №2:
getX — это не решение для всего, но у него есть несколько полезных методов, которые могут помочь вам достичь того, чего вы хотите. Например, вы можете использовать a validator
вместе с SnackBar
для окончательной проверки. Вот фрагмент кода, который может помочь вам понять основы.
TextFormField(
controller: emailController,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if (!GetUtils.isEmail(value))
return "Email is not valid";
else
return null;
},
),
GetUtils
имеет несколько удобных методов для быстрой проверки, и вам нужно будет изучить каждый метод, чтобы увидеть, соответствует ли он вашим потребностям.
Комментарии:
1. Потрясающий комментарий, использование GetUtils и autovalidatemode упрощает задачу!!