Flutter表单生成与管理插件reactive_forms_generator的使用
Flutter表单生成与管理插件reactive_forms_generator的使用
reactive_forms_generator
是一个用于 reactive_forms
的代码生成器,能够帮助开发者节省大量时间并使表单类型安全。本文将详细介绍如何安装和使用该插件,并提供完整的示例代码。
动机
在传统的 reactive_forms
中,表单字段通常通过字符串标识符定义,这会导致静态类型检查的问题。此外,输出通常是 Map<String, Object>
,对于强类型语言来说不太友好。reactive_forms_generator
解决了这些问题,通过代码生成的方式自动生成表单模型和相关代码。
如何使用
最低要求
- Dart SDK: >=2.12.0 <3.0.0
- Flutter: >= 2.2.0
安装
首先需要在 pubspec.yaml
文件中添加必要的依赖:
dependencies:
reactive_forms:
reactive_forms_annotations:
dev_dependencies:
build_runner:
reactive_forms_generator:
这会安装以下三个包:
- build_runner:运行代码生成器的工具
- reactive_forms:表单引擎本身
- reactive_forms_generator:代码生成器
- reactive_forms_annotations:包含注解的包
忽略生成文件的 lint 警告
生成的代码可能会导致 linter 报警。可以通过修改 analysis_options.yaml
来忽略这些警告:
analyzer:
exclude:
- "**/*.gform.dart"
运行生成器
确保在运行生成器之前导入必要的包,并在文件顶部添加 part
关键字:
import 'package:flutter/material.dart';
import 'package:reactive_forms/reactive_forms.dart';
import 'package:reactive_forms_annotations/reactive_forms_annotations.dart';
part 'my_file.gform.dart';
然后根据你的项目是否依赖 Flutter,选择以下命令之一来运行生成器:
- 如果项目依赖 Flutter:
flutter pub run build_runner build
- 如果项目不依赖 Flutter:
dart pub run build_runner build
特性
基础示例
模型
首先定义一个简单的登录表单模型:
class Basic {
final String email;
final String password;
Basic({this.email = '', this.password = ''});
}
注解
接下来为模型添加注解,以便生成器可以生成相应的表单代码:
import 'package:reactive_forms_annotations/reactive_forms_annotations.dart';
@Rf()
class Basic {
final String email;
final String password;
Basic({
@RfControl() this.email = '',
@RfControl() this.password = '',
});
}
验证
为表单字段添加验证规则:
import 'package:example/helpers.dart';
import 'package:reactive_forms_annotations/reactive_forms_annotations.dart';
@Rf()
class Basic {
final String email;
final String password;
Basic({
@RfControl(
validators: const [RequiredValidator()],
) this.email = '',
@RfControl(
validators: const [RequiredValidator()],
) this.password = '',
});
}
表单
基于生成的代码构建表单:
final form = BasicFormBuilder(
model: Basic(),
builder: (context, formModel, child) {
return Column(
children: [
ReactiveTextField<String>(
formControl: formModel.emailControl,
validationMessages: {
ValidationMessage.required: (_) => 'The email must not be empty',
},
decoration: const InputDecoration(labelText: 'Email'),
),
const SizedBox(height: 8.0),
ReactiveTextField<String>(
formControl: formModel.passwordControl,
obscureText: true,
validationMessages: {
ValidationMessage.required: (_) => 'The password must not be empty',
},
textInputAction: TextInputAction.done,
decoration: const InputDecoration(labelText: 'Password'),
),
const SizedBox(height: 8.0),
ReactiveBasicFormConsumer(
builder: (context, form, child) {
return ElevatedButton(
child: Text('Submit'),
onPressed: form.form.valid
? () {
print(form.model.email);
print(form.model.password);
}
: null,
);
},
),
],
);
},
);
动态表单与 FormArray
模型
定义一个邮件列表模型:
class MailingList {
final List<String?> emailList;
MailingList({
this.emailList = const [],
});
}
注解
为模型添加注解:
import 'package:example/helpers.dart';
import 'package:reactive_forms_annotations/reactive_forms_annotations.dart';
@Rf()
class MailingList {
final List<String?> emailList;
MailingList({
@RfArray(
validators: const [
MailingListValidator(),
],
) this.emailList = const [],
});
}
验证
定义自定义验证器:
class MailingListValidator extends Validator<dynamic> {
const MailingListValidator() : super();
@override
Map<String, dynamic>? validate(AbstractControl control) {
final formArray = control as FormArray<String>;
final emails = formArray.value ?? [];
final test = <String>{};
final result = emails.fold<bool>(true,
(previousValue, element) => previousValue && test.add(element ?? ''));
return result ? null : <String, dynamic>{'emailDuplicates': true};
}
}
表单
基于生成的代码构建动态表单:
final form = MailingListFormBuilder(
model: MailingList(),
builder: (context, formModel, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: ReactiveFormArray<String>(
formArray: formModel.emailListControl,
builder: (context, formArray, child) =>
Column(
children: formModel.emailListValue
.asMap()
.map((i, email) {
return MapEntry(
i,
ReactiveTextField<String>(
formControlName: i.toString(),
validationMessages: {
'email': (_) => 'Invalid email',
},
decoration: InputDecoration(
labelText: 'Email ${i}'),
));
})
.values
.toList(),
),
),
),
SizedBox(width: 16),
ElevatedButton(
onPressed: () {
formModel.addEmailListItem('');
},
child: const Text('add'),
)
],
),
SizedBox(height: 16),
ReactiveMailingListFormConsumer(
builder: (context, form, child) {
final errorText = {
'emailDuplicates': 'Two identical emails are in the list',
};
final errors = <String, dynamic>{};
form.emailListControl.errors.forEach((key, value) {
final intKey = int.tryParse(key);
if (intKey == null) {
errors[key] = value;
}
});
if (form.emailListControl.hasErrors && errors.isNotEmpty) {
return Text(errorText[errors.entries.first.key] ?? '');
} else {
return Container();
}
},
),
SizedBox(height: 16),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ElevatedButton(
onPressed: () {
if (formModel.form.valid) {
print(formModel.model);
} else {
formModel.form.markAllAsTouched();
}
},
child: const Text('Sign Up'),
),
ReactiveMailingListFormConsumer(
builder: (context, form, child) {
return ElevatedButton(
child: Text('Submit'),
onPressed: form.form.valid ? () {} : null,
);
},
),
],
)
],
);
},
);
完整示例
以下是一个完整的示例,展示了如何在 Flutter 应用中使用 reactive_forms_generator
:
import 'package:flutter/material.dart';
import 'package:reactive_forms/reactive_forms.dart';
import 'package:reactive_forms_annotations/reactive_forms_annotations.dart';
part 'basic_form.gform.dart';
@Rf()
class Basic {
final String email;
final String password;
Basic({
@RfControl(
validators: const [RequiredValidator(), EmailValidator()],
) this.email = '',
@RfControl(
validators: const [RequiredValidator(), MinLengthValidator(8)],
) this.password = '',
});
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LoginFormWidget(),
);
}
}
class LoginFormWidget extends StatelessWidget {
final form = BasicFormBuilder(
model: Basic(),
builder: (context, formModel, child) {
return Column(
children: [
ReactiveTextField<String>(
formControl: formModel.emailControl,
validationMessages: {
ValidationMessage.required: (_) => 'The email must not be empty',
ValidationMessage.email: (_) => 'Invalid email format',
},
decoration: const InputDecoration(labelText: 'Email'),
),
const SizedBox(height: 8.0),
ReactiveTextField<String>(
formControl: formModel.passwordControl,
obscureText: true,
validationMessages: {
ValidationMessage.required: (_) => 'The password must not be empty',
ValidationMessage.minLength: (_) => 'Minimum length is 8 characters',
},
textInputAction: TextInputAction.done,
decoration: const InputDecoration(labelText: 'Password'),
),
const SizedBox(height: 8.0),
ReactiveBasicFormConsumer(
builder: (context, form, child) {
return ElevatedButton(
child: Text('Submit'),
onPressed: form.form.valid
? () {
print(form.model.email);
print(form.model.password);
}
: null,
);
},
),
],
);
},
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Login Form'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: form,
),
);
}
}
通过上述步骤和示例代码,你可以轻松地使用 reactive_forms_generator
插件来生成和管理 Flutter 表单。希望本文对你有所帮助!
更多关于Flutter表单生成与管理插件reactive_forms_generator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter表单生成与管理插件reactive_forms_generator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,reactive_forms_generator
是一个强大的 Flutter 插件,用于动态生成和管理表单。它通过代码生成简化了表单处理流程,提高了开发效率。以下是一个基本的示例,展示如何使用 reactive_forms_generator
来创建和管理表单。
1. 添加依赖
首先,在你的 pubspec.yaml
文件中添加 reactive_forms
和 reactive_forms_generator
依赖:
dependencies:
flutter:
sdk: flutter
reactive_forms: ^x.y.z # 请使用最新版本号
reactive_forms_generator: ^x.y.z # 请使用最新版本号
build_runner: ^x.y.z # 确保安装了 build_runner 以支持代码生成
2. 创建表单模型
定义一个表单模型类,并使用注解来标记字段和验证规则。例如,创建一个 UserForm
类:
import 'package:reactive_forms/reactive_forms.dart';
import 'package:reactive_forms_generator/reactive_forms_generator.dart';
part 'user_form.g.dart'; // 这是代码生成文件
@reactiveFormClass
class UserForm {
@requiredField()
@minLength(3)
@maxLength(30)
String? name;
@requiredField()
@email()
String? email;
@requiredField()
@minLength(6)
String? password;
UserForm() : super();
factory UserForm.fromJson(Map<String, dynamic> json) =>
_$UserFormFromJson(json);
Map<String, dynamic> toJson() => _$UserFormToJson(this);
}
// 运行以下命令生成代码:
// flutter pub run build_runner build
3. 生成代码
在终端中运行以下命令来生成代码:
flutter pub run build_runner build
4. 创建表单控件
在你的 Flutter 组件中,使用生成的表单控件来创建和管理表单。例如:
import 'package:flutter/material.dart';
import 'package:reactive_forms/reactive_forms.dart';
import 'user_form.dart'; // 导入生成的表单类
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Reactive Forms Example'),
),
body: ReactiveForm(
formGroup: FormGroup.fromGroup(UserForm.initial()),
builder: (formGroup) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
ReactiveTextField<String>(
formControlName: 'name',
decoration: InputDecoration(labelText: 'Name'),
),
ReactiveTextField<String>(
formControlName: 'email',
decoration: InputDecoration(labelText: 'Email'),
),
ReactiveTextField<String>(
formControlName: 'password',
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
),
ReactiveFormErrors(formGroup: formGroup),
ElevatedButton(
onPressed: () {
if (formGroup.valid) {
// 处理有效表单数据
print(formGroup.value);
}
},
child: Text('Submit'),
),
],
),
);
},
),
),
);
}
}
5. 运行应用
现在,你可以运行你的 Flutter 应用,并看到一个带有动态生成的表单控件的页面。这些控件会根据你定义的验证规则进行验证,并在表单提交时显示错误信息(如果有的话)。
这个示例展示了如何使用 reactive_forms_generator
来动态生成和管理 Flutter 表单。通过代码生成,你可以显著减少手动编写表单控件和验证逻辑的工作量。