Flutter BLoC 库中带有验证的文本字段

Posted

技术标签:

【中文标题】Flutter BLoC 库中带有验证的文本字段【英文标题】:Text fields with validation in the Flutter BLoC library 【发布时间】:2020-11-28 23:28:28 【问题描述】:

我正在尝试学习 Flutter 中的 BLoC 模式,但我就是不明白。我按照 Udemy 上的教程为简单的登录表单生成了以下代码:

BLoC Class

import 'dart:async';

import 'package:login_bloc/src/blocs/validators.dart';

class LoginBloc extends Validators 
  final _email = StreamController<String>();
  final _password = StreamController<String>();

  // Return Stream data
  // Streams are run thru validator first
  Stream<String> get getEmail => _email.stream.transform(validateEmail);
  Stream<String> get getPassword => _password.stream.transform(validatePassword);

  // Change data on stream
  Function(String) get changeEmail => _email.sink.add;
  Function(String) get changePassword => _password.sink.add;

  // Named by convention. Quiets Dart warning.
  dispose() 
    _email.close();
    _password.close();
  

UI Class

import 'package:flutter/material.dart';
import 'package:login_bloc/src/blocs/login_bloc.dart';
import 'package:login_bloc/src/providers/provider.dart';

class LoginScreen extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    final loginBloc = Provider.of(context);
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: SafeArea(
        child: Column(
          children: <Widget>[
            emailField(loginBloc),
            passwordField(loginBloc),
            SizedBox(height: 10.0),
            submitButton(),
          ],
        ),
      ),
    );
  

  Widget emailField(LoginBloc loginBloc) 
    return StreamBuilder<Object>(
        stream: loginBloc.getEmail,
        builder: (context, snapshot) 
          return TextField(
            keyboardType: TextInputType.emailAddress,
            decoration: InputDecoration(
              hintText: 'you@example.com',
              labelText: 'Email Address',
              errorText: snapshot.error,
            ),
            onChanged: loginBloc.changeEmail,
          );
        );
  

  Widget passwordField(LoginBloc loginBloc) 
    return StreamBuilder<Object>(
        stream: loginBloc.getPassword,
        builder: (context, snapshot) 
          return TextField(
            obscureText: true,
            keyboardType: TextInputType.text,
            decoration: InputDecoration(
              labelText: 'Password',
              errorText: snapshot.error,
            ),
            onChanged: loginBloc.changePassword,
          );
        );
  

  Widget submitButton() 
    return RaisedButton(
      child: Text(
        'Login',
        style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
      ),
      color: Colors.blue,
      onPressed: () => ,
    );
  


验证器非常简单:基本上,电子邮件需要一个“@”符号,密码必须超过 4 个字符。当我跟随时这是有道理的,但是一旦我尝试自己实施,它就会变得模糊。因此,作为我学习的一部分,我想尝试转换这个简单的登录表单以利用 BLoC 和 Flutter_BLoC 库,认为它会抽象出一些复杂性并且更容易理解。

经过大量工作,我仍然不知道如何指定我要保持什么状态,以及我要通过什么事件。我已经用完了在 YouTube 上可以查看的教程,而且它们几乎都使用计数器应用程序作为具有单个 INT 变量类型的示例。图书馆刚刚进行了一次大修,而且几乎所有的教程现在都已经过时了,这也让事情变得复杂。

是否有可用的示例说明如何使用 v6 库执行此操作?特别是,我对如何仅在两个字段均已验证后才激活提交按钮感兴趣。

【问题讨论】:

【参考方案1】:

你可以使用 rxdart 包,可以在here 找到。 Rxdart 为 Dart Streams 和 StreamControllers 添加了额外的功能。其中之一是combineLatest2(),它基本上结合了 2 个流的值并作为单个流值发出。

您可以从这个link 阅读更多关于combineLatest2() 方法的信息。

例子:

Stream<bool> get isValid => Rx.combineLatest2(getEmail, getPassword, (a,b) => true);

【讨论】:

以上是关于Flutter BLoC 库中带有验证的文本字段的主要内容,如果未能解决你的问题,请参考以下文章

flutter_bloc - 每个 Bloc 有多个存储库,还是只有一个?

Flutter 中的自动填充文本字段

使用flutter_bloc提交时如何验证表单?

Flutter BLoC 架构 - 角色

如何将 Flutter Bloc 与 Firebase 电话身份验证一起使用

应该将 Bloc 模式用于颤动文本字段,如果是的话如何?