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 示例

simple_form
示例输出

简单用法

安装

将以下依赖项添加到您的 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、属性名称和属性值。
要提交表单,通常需要序列化此列表并将其发送回服务器。

GitHub

https://github.com/OndrejKunc/flutter_dynamic_forms