flutter_dynamic_forms
一系列 Flutter 和 Dart 库,允许您在应用程序外部动态定义复杂表单并在运行时使用它。
主要目标
此项目的理念是能够通过服务器定义包含所有输入、验证逻辑和其他规则的表单,并在不重新部署应用程序的情况下在 Flutter 客户端中使用它。
通过使用类似 XAML 的语法或 JSON 来定义表单来实现。它有自己的表达式语言来描述每个元素的属性之间的所有关系。
请参阅 示例项目,其中包含可运行的演示。
表单定义示例
<?xml version="1.0" encoding="UTF-8"?>
<form id="form1">
<text
id="firstName"
label="Enter your first name">
</text>
<text
id="lastName"
label="Enter your last name">
<text.validations>
<requiredValidation
message="Last name is required"/>
</text.validations>
</text>
<label
id="fullNameLabel">
<label.value>
<expression>
<![CDATA[
@firstName + (length(@firstName) > 0 && length(@lastName) > 0 ? " " : "") + @lastName
]]>
</expression>
</label.value>
</label>
<label>
<label.value>
<expression>
<![CDATA[
"Welcome " + @fullNameLabel + "!"
]]>
</expression>
</label.value>
<label.isVisible>
<expression>
<![CDATA[
!@hideWelcomeCheckBox && length(@fullNameLabel) > 0
]]>
</expression>
</label.isVisible>
</label>
<checkBox
id="hideWelcomeCheckBox"
value="false"
label="Hide welcome message"/>
</form>
如果您更喜欢使用 JSON 来描述您的表单,请查看 json 示例。

示例输出
简单用法
安装
将以下依赖项添加到您的 pubspec.yaml 文件中
flutter_dynamic_forms: ^0.5.0
flutter_dynamic_forms_components: ^0.4.0
显示表单
flutter_dynamic_forms_components 库包含一组预定义的组件,例如文本输入、标签、复选框、单选按钮组等。为了让您的应用程序使用这些组件,您需要执行以下步骤
首先,您需要创建一个名为 FormManager 的对象。您可以将其放在 StatefulWidget 的状态的 initState 方法中
//Get your data somewhere, for demo purposes we use local assets
var data = await rootBundle.loadString("assets/test_form1.xml");
//Use either XmlFormParserService or JsonParserService depending on your form format.
//For default component set use the predefined parser list.
var formManagerBuilder = FormManagerBuilder(XmlFormParserService(getDefaultParserList()));
//Store the _formManager in your state.
_formManager = formManagerBuilder.build(data);
FormManager 有一个名为 form 的 getter,它是您的 xml/json 表单在 Dart 中的对象表示。FormManager 还可以对表单执行一些有用的操作,例如在 UI 中发生某些事情时操作表单的状态、验证表单或收集表单中的所有数据,以便例如将其发送回服务器。
在渲染表单之前,您还需要初始化 FormRenderService。此服务获取渲染器列表,其中每个渲染器控制屏幕上每个组件的渲染方式
_formRenderService = FormRenderService(
renderers: getReactiveRenderers(),
dispatcher: _onFormElementEvent,
);
在此示例中,我们使用一组预定义的渲染器。响应式(reactive)一词意味着每个组件都将监听表单模型中的更改并自行更新。dispatcher 参数是在执行某些操作(例如选中复选框)时从渲染器发送的回调方法。我们将仅将此操作委托给我们的 FormManager
void _onFormElementEvent(FormElementEvent event) {
if (event is ChangeValueEvent) {
_formManager.changeValue(
value: event.value, elementId: event.elementId, propertyName: event.propertyName);
}
}
由于我们使用响应式渲染器,因此我们无需在此方法末尾调用 setState() 来重新渲染表单。该库本身将确保根据此更改仅更新表单元素的正确属性。
之后,您必须通知小部件您的表单已准备好使用
setState(() {
_form = _formManager.form;
});
最后定义构建方法
@override
Widget build(BuildContext context) {
if (_form == null) {
return Center(
child: CircularProgressIndicator(),
);
}
return Center(
child: SingleChildScrollView(
child: _formRenderService.render(_form, context),
),
);
}
就是这样!现在您可以在实际操作中看到您的表单了。
从表单收集数据
将数据发送回服务器过程的理念是,我们不应发送整个表单,而只发送用户更改的值。
要收集数据,只需调用
List<FormItemValue> data = formManager.getFormData()
它包含在组件解析器定义中标记为可变的所有属性的列表。在默认组件中,这些是用户期望更改的属性。每个项目包含源元素的 ID、属性名称和属性值。
要提交表单,通常需要序列化此列表并将其发送回服务器。