我在Flutter中使用reactive_forms,这是一个模型驱动的表单库,它的灵感来自Angular reactive forms。
添加一个名为"nickName"的formControl表单非常简单:
final _form = FormGroup({
'nickName':
FormControl<String>(validators: [Validators.required]),
});
我的问题是,拥有表单控制"不是很常见,也是很好的做法吗;昵称";绑定到域模型的属性?因为这是我在Angular中研究的另一个代码库中所做的。
我确实有这个表单的域模型(尽管它的字段比表单包含的字段多。其余字段在以下页面的表单中设置,就像设置向导一样(:
class UserRegistrationEntity {
String nickName;
String email;
String confirmEmail;
String password;
String confirmPassword;
}
我可以创建这样的模型:
final userRegistration = UserRegistrationEntity();
但是,我现在如何将userRegistration
的nickName
字段绑定到我的表单控件?我希望表单库有一个等效于ngModel
的字段,以便在表单控件上设置模型的字段。
或者这不是Flutter中所做的事情?
示例:https://angular.io/api/forms/NgModel#using-ngmodel-on-a-standalone-control
从我在扑动中使用reactive_forms
开始,我没有看到任何与ngModel
等效的东西。这是因为像ReactiveTextField
这样的元素被设计为具有与窗口小部件(双向绑定(的双重绑定能力
这就是为什么不包括onChanged
这样的属性,它类似于ngModel方法#ngOnChanges()
因此,要将userRegistration的nickName字段绑定到表单控件,需要使用ViewModel
和Provider
。
所以你的代码看起来是这样的:
class YourViewModel {
final _form = FormGroup({
'nickName':
FormControl<String>(validators: [Validators.required]),
});
//assuming you are signing in
void signIn() {
final credentials = this.form.value;
//the rest of your signIn code
}
}
class YourScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final viewModel = Provider.of<YourViewModel>(context, listen: false);
return ReactiveForm(
formGroup: viewModel.form,
child: Column(
children: <Widget>[
ReactiveTextField(
formControlName: 'nickName',
),
ReactiveFormConsumer(
builder: (context, form, child) {
return RaisedButton(
child: Text('Submit'),
// if the form is valid, sign-in or whatever you need to do with the form data (I have used signIn)
onPressed: form.valid ? viewModel.signIn : null,
);
},
),
],
),
);
}
}
结论
ngModel是一个绑定输入的指令,Reactive Forms也这样做,并保持视图和模型之间的分离,同时仍然保持数据同步。因此,NO显然需要将您的数据绑定到域层,而reactive_forms
完全不需要这样做,因为过程是内置的。
更新2022-reactive_forms_generator发布。它是reactive_forms的代码生成器。它生成了大量的表单功能;一个例子是,它将强类型模型绑定到表单。它有一个FormModel:
abstract class FormModel<TModel> {
FormModel({required this.form});
final FormGroup form;
TModel get model;
}
并且form
和model
是同步的(model
是一个getter,它通过检索每个表单值来返回强类型模型(。