Flutter数据流验证插件stream_fluent_validation的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter数据流验证插件stream_fluent_validation的使用

Stream Fluent Validation 是一个用于 Flutter 开发者的验证库。它支持对字符串、EditText、TextView、AutoCompleteTextView、TextInputLayout 和 Spinner 进行文本验证。它包含了许多内置的验证规则,例如电子邮件验证和特殊字符验证等。

快速使用 Stream Fluent Validation

例如,你可以这样验证表单:

final LoginValidation loginValidation = LoginValidation();

class LoginValidation extends AbstractValidator<LoginValidation> {
  StreamValidator<String> email = StreamValidator<String>();
  StreamValidator<String> password = StreamValidator<String>();

  LoginValidation() {
    ruleFor((e) => (e as LoginValidation).email)
        .isNotEmpty()
        .withMessage("email should not be empty")
        .emailAddress()
        .withMessage("email should be valid !!.");

    ruleFor((e) => (e as LoginValidation).password)
        .between(3, 4)
        .withMessage("password should contain from 3 to 4 digits !!.");
  }
}

// 后续代码
StreamBuilder(
  stream: loginValidation.email.stream,
  builder: (context, snap) {
    return TextField(
      keyboardType: TextInputType.emailAddress,
      onChanged: loginValidation.email.valueChange,
      decoration: InputDecoration(
        labelText: "Email address",
        hintText: "you@example.com",
        errorText: snap.hasError ? "${snap.error}" : null,
      ),
    );
  },
)

StreamBuilder(
  stream: loginValidation.password.stream,
  builder: (context, snap) {
    return TextField(
      keyboardType: TextInputType.number,
      onChanged: loginValidation.password.valueChange,
      obscureText: true,
      decoration: InputDecoration(
        labelText: "Password",
        hintText: "******",
        errorText: snap.hasError ? "${snap.error}" : null,
      ),
    );
  },
);

多重验证检查及消息

Stream Fluent Validation 还支持多重验证检查,例如:

class LoginValidation extends AbstractValidator<LoginValidation> {
  StreamValidator<String> email = StreamValidator<String>();

  LoginValidation() {
    ruleFor((e) => (e as LoginValidation).email)
        .isNotEmpty()
        .withMessage("email should not be empty")
        .emailAddress()
        .withMessage("email should be valid !!.");
  }
}

创建自定义验证规则

你还可以通过扩展 must 验证规则来添加自己的自定义验证规则:

ruleFor((e) => (e as LoginValidation).userName)
    .must((Object value) {
      return value.toString().isNotEmpty &&
          value.toString().contains(".") &&
          value.toString().length >= 3;
    })
    .withMessage("user name is not correct");

内置验证器

以下是一些内置的验证器:

  • notEmpty - 检查对象是否为字符串且不为空
  • empty - 检查对象是否为字符串且为空
  • notEqual - 检查当前流是否不等于另一个
  • equal - 检查当前流是否等于另一个
  • notEqualToConstValue - 检查值是否不等于另一个
  • equalToConstValue - 检查值是否等于另一个
  • length - 检查对象是否为字符串且在两个数字之间

其他内置验证器

这些验证器不包括在默认的 C# 版本中:

  • isValidEmailAddress - 检查对象是否为字符串且为有效的电子邮件地址

示例代码

以下是完整的示例代码:

import 'package:flutter/material.dart';
import 'package:stream_fluent_validation/fluent_validation.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const LoginPage(),
    );
  }
}

var loginController = LoginController();

class LoginController {
  final LoginValidation loginValidation = LoginValidation();

  void login() {
    if (!loginValidation.validate()) {
      print("you can not login");
      return;
    }
    print("your login succeed ");
  }
}

class LoginValidation extends AbstractValidator<LoginValidation> {
  StreamValidator<String> email = StreamValidator<String>();
  StreamValidator<String> password = StreamValidator<String>();

  LoginValidation() {
    ruleFor((e) => (e as LoginValidation).email)
        .notEmpty()
        .withMessage("email should not be empty")
        .emailAddress()
        .withMessage("email should be valid !!.");

    ruleFor((e) => (e as LoginValidation).password)
        .length(3, 4)
        .withMessage("password should contain from 3 to 4 digits !!.");
  }
}

class LoginPage extends StatelessWidget {
  const LoginPage({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: const [
          SizedBox(height: 30),
          EmailInput(),
          SizedBox(height: 30),
          PasswordInput(),
          SizedBox(height: 30),
          SubmitButton(),
        ],
      ),
    );
  }
}

class EmailInput extends StatelessWidget {
  const EmailInput({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) => StreamBuilder(
        stream: loginController.loginValidation.email.stream,
        builder: (context, snap) {
          return TextField(
            keyboardType: TextInputType.emailAddress,
            onChanged: loginController.loginValidation.email.valueChange,
            decoration: InputDecoration(
              labelText: "Email address",
              hintText: "you@example.com",
              errorText: snap.hasError ? "${snap.error}" : null,
            ),
          );
        },
      );
}

class PasswordInput extends StatelessWidget {
  const PasswordInput({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) => StreamBuilder(
        stream: loginController.loginValidation.password.stream,
        builder: (context, snap) {
          return TextField(
            keyboardType: TextInputType.number,
            onChanged: loginController.loginValidation.password.valueChange,
            obscureText: true,
            decoration: InputDecoration(
              labelText: "Password",
              hintText: "******",
              errorText: snap.hasError ? "${snap.error}" : null,
            ),
          );
        },
      );
}

class SubmitButton extends StatelessWidget {
  const SubmitButton({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return RaisedButton(
      onPressed: () {
        loginController.login();
      },
      color: Colors.blue,
      child: const Text(
        "Login",
        style: TextStyle(color: Colors.white),
      ),
    );
  }
}

更多关于Flutter数据流验证插件stream_fluent_validation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据流验证插件stream_fluent_validation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


stream_fluent_validation 是一个用于 Flutter 的插件,旨在帮助开发者在处理数据流时进行验证。它结合了 StreamFluent Validation 的概念,使得数据验证更加流畅和直观。以下是如何使用 stream_fluent_validation 的基本指南。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 stream_fluent_validation 依赖:

dependencies:
  flutter:
    sdk: flutter
  stream_fluent_validation: ^1.0.0  # 使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 导入包

在你的 Dart 文件中导入 stream_fluent_validation 包:

import 'package:stream_fluent_validation/stream_fluent_validation.dart';

3. 创建验证器

你可以通过扩展 ValidatorBase 类来创建自定义验证器,或者使用内置的验证规则。以下是一个简单的示例,展示了如何创建一个验证器来验证电子邮件地址:

class EmailValidator extends ValidatorBase<String> {
  [@override](/user/override)
  Stream<String?> validate(String value) {
    if (value.isEmpty) {
      return Stream.value('Email is required');
    }
    if (!RegExp(r"^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(value)) {
      return Stream.value('Invalid email address');
    }
    return Stream.value(null); // 返回 null 表示验证通过
  }
}

4. 使用验证器

你可以将验证器与 Stream 结合使用,以便在数据流中实时验证输入。以下是一个简单的示例,展示了如何在 TextField 中使用 EmailValidator

class MyForm extends StatefulWidget {
  [@override](/user/override)
  _MyFormState createState() => _MyFormState();
}

class _MyFormState extends State<MyForm> {
  final emailController = StreamController<String>();
  final emailValidator = EmailValidator();

  [@override](/user/override)
  void dispose() {
    emailController.close();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          onChanged: (value) {
            emailController.add(value);
          },
          decoration: InputDecoration(
            labelText: 'Email',
          ),
        ),
        StreamBuilder<String?>(
          stream: emailController.stream.transform(emailValidator),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Text(
                snapshot.data!,
                style: TextStyle(color: Colors.red),
              );
            }
            return Container();
          },
        ),
      ],
    );
  }
}
回到顶部