前身 - 在 Flutter 中轻松构建表单

使用流畅的 Schema API 在 Flutter 中轻松构建表单。

former_widgets

动机

Formik 是我最喜欢的 React 库之一。它是一个表单库,大大减少了
用于跟踪字段值、验证和表单提交的样板代码。

Flutter 中的表单构建也存在类似的问题

  • 开发人员必须手动跟踪字段值,例如使用 TextEditingController
  • 验证和错误处理需要命令式逻辑。

这就是 former 的用武之地。

安装

最新版本: 0.2.0-rc.1

注意:此软件包处于预发布阶段 - API 未来可能会发生重大变化。

former 添加到 pubspec.yamldependencies 部分

dependencies:
  # ...your other dependencies
  former: # optionally lock-in a version

并将 former_gen 添加到 dev_dependencies 部分

dev_dependencies:
  # ...your other dependencies
  former_gen: # optionally lock-in a version

最后,运行 flutter pub get

功能

former 提供以下功能

  • 全局启用/禁用表单
  • 声明式表单验证
  • 通过 Former 小部件自动跟踪值
  • 使用 FormerError 小部件轻松处理错误。
  • 类型安全的表单访问。

用法

创建表单

former 通过检查您的表单类并生成相应的代码来使其与 former
API 一起工作。

首先,让我们在 my_form.dart 中创建我们的表单类

import 'package:former_gen/former_gen.dart';

@Formable()
abstract class _MyForm extends FormerForm {
}

有几点需要注意

  • 表单类是抽象的且私有的。这是因为在 former 可以使用之前,必须混合一些逻辑。
  • 表单类继承自 FormerForm。它将我们的表单类与 former 接口,以便 former
    内部可以使用它。

FormerForm 要求子类实现方括号运算符。在我们的抽象类中不需要
因为 former 的代码生成将处理该负担。我们只需要实现 submit 方法。例如,它可以包括将表单提交
给某个 API 进行进一步处理。

为了简单起见,我们对 submit 的实现只返回一个空的 Future 值。

请注意,submit 方法
接受一个 BuildContext。这是我们稍后将用于提供此表单的 Former 小部件使用的相同 BuildContext
当您想访问上下文中其他 Provider 时,这可能很有用。只需确保您想访问的 Provider
是提供表单的 Former 小部件的父级。

@Formable()
abstract class _MyForm extends FormerForm {
  @override
  Future<void> submit(BuildContext context) {
    // TODO: implement submit()
    return Future.value();
  }
}

让我们也为我们的表单添加一些字段

@Formable()
abstract class _MyForm extends FormerForm {
  String username = '';
  String email = '';

  @override
  Future<void> submit(BuildContext context) {
    // TODO: implement submit()
    return Future.value();
  }
}

在混合生成的 mixin 之前,我们的表单类是无法使用的,该 mixin 使表单可以使用方括号运算符“索引”,
并且还包含表单中字段的类型信息。在类声明之前添加以下内容

class MyForm = _MyForm with _$MyForm;

并添加此

part 'my_form.g.dart';

以导入生成的代码。

Dart 分析器将抱怨无法识别的符号和导入。要解决此问题,请通过 build_runner
启动代码生成

flutter pub run build_runner build

指定要求

假设我们的表单有以下要求

  • 用户名至少应为 10 个字符,但不超过 50 个字符。
  • 电子邮件字段,嗯,应该包含一个有效的电子邮件。

没有 former,这必须以命令式的方式完成,例如,通过检查字符串的长度。
former 用于指定要求的超声明式 API 使一切变得轻松易读。您所要做的就是
创建为您生成的 schema 类。在 my_form.dart 中,


final schema = MyFormSchema(
  username: StringMust()
    ..hasMinLength(10)
    ..hasMaxLength(50),
  email: StringMust()
    ..beAnEmail(),
);

正如您所看到的,API 非常自明。请注意级联运算符 .. 的使用 - 在 Dart 中,而不是
返回 this 进行方法链式调用,而是首选级联运算符 ..

构建表单控件

former 导出各种与给定表单交互的小部件。首先,让我们创建我们的表单小部件

import 'package:flutter/material.dart';
import 'package:former/former.dart';

import 'my_form.dart';

class Form extends StatelessWidget {
  @override
  Widget build() {
    return Column(
      children: [
        FormerTextField<MyForm>(field: MyFormField.username),
        FormerTextField<MyForm>(field: MyFormField.email),
        ElevatedButton(
            onPressed: () {
              Former.of<MyForm>(context, listen: false).submit();
            },
            child: Text('Submit form')
        )
      ],
    );
  }
}

我们的表单包含两个文本字段,分别控制 usernameemail 字段。MyFormField
类是为您自动生成的,因此您不必自己创建一个。

按钮被点击时,MyFormsubmit 方法会被调用来提交表单。除了提交
表单,Former.of(context) 让您可以访问

  • 当前表单,通过 .form。例如,您可以访问当前用户名字段的值
    使用 Former.of<MyForm>(context).form.username
  • 使用 .isFormEnabled getter/setter 来启用/禁用表单。当表单被禁用时,所有控制
    表单的 former 控件也会自动禁用。
  • 给定字段的错误,使用 .errorOf(field),它会返回因验证失败而产生的错误消息。
    当字段有效或尚未执行任何验证时,它返回一个空字符串。

这是一个极其简化的表单版本,用于展示小部件。实际上,每个 Former 控件都应该
有一个标签来描述它们的作用。将来,可能会有一个小部件将标签附加到 Former 控件。
现在,它必须手动完成。

整合所有内容

最后,我们要做的就是用 Former 小部件包装我们的表单小部件

import 'package:flutter/material.dart';
import 'package:former/former.dart';

import 'my_form.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build() {
    return MaterialApp(
      home: Scaffold(
        body: Former(
          form: () => MyForm(),
          schema: () => schema, // exported from my_form.dart
          child: _MyForm(),
        ),
      ),
    );
  }
}

源代码

完整的源代码可在 example 文件夹中找到。

API

可用小部件

以下小部件可供 former 使用

  • FormerTextField
  • FormerCheckbox
  • FormerSwitch
  • FormerSlider

开发中

  • FormerRadio
  • FormerDropdownButton

Schema

以下验证器可用于验证表单字段。每个验证器都有各种方法,可以施加额外的
对给定值(称为要求方法)的要求。

每个要求方法都接受一个可选的错误消息参数,当值不符合该
要求时会返回该消息。

  • StringMust
  • NumberMust
  • BoolMust

实现 Validator 类以创建自定义验证逻辑。

GitHub

https://github.com/kennethnym/former