如何在flutter中使用流转换器根据另一个输入字段的值验证输入

时间:2019-12-12 05:09:35

标签: authentication flutter dart rxdart

我有一个包含电子邮件,密码和确认密码字段的注册表格。我要实现的是正确验证输入。目前,我使用的是天真的算法来验证电子邮件和密码,这很好。对于确认密码字段,我希望它与有效密码的条件匹配,并且该值应与密码的值匹配。我要使用流转换还是完全不同的方法?

身份验证块

  final _emailTFController = TextEditingController();
  final _passwordTFController = TextEditingController();
  final _confirmPasswordTFController = TextEditingController();

  Stream<String> get emailStream =>
      _emailController.stream.transform(Validators.validateEmail);

  Stream<String> get passwordStream =>
      _passwordController.stream.transform(Validators.validatePassword);

验证者

import 'dart:async';

class Validators {
  static final validateEmail =
      StreamTransformer<String, String>.fromHandlers(handleData: (email, sink) {
    if (email.contains('@')) {
      sink.add(email);
    } else {
      sink.addError('Enter a valid email');
    }
  });

  static final validatePassword = StreamTransformer<String, String>.fromHandlers(
      handleData: (password, sink) {
    if (password.length > 4) {
      sink.add(password);
    } else {
      sink.addError('Invalid passord, please enter more than 4 characters.');
    }
  });
}

2 个答案:

答案 0 :(得分:0)

使用BehaviourSubject代替流控制器

final passwordController=BehaviorSubject<String>();

并通过如下的doOnData方法使用ConfirmPassword函数

Stream<String> get confirmpassword =>
      confirmpasswordController.stream.transform(confirmPasswordValidator)
          .doOnData((String c){
        // If the password is accepted (after validation of the rules)
        // we need to ensure both password and retyped password match
        if (0 != passwordController.value.compareTo(c)){
          // If they do not match, add an error
          confirmpasswordController.addError("Confirm Password donot match");
        }
      });

答案 1 :(得分:0)

        class PasswordManager{
            BehaviorSubject<String> _password =
                  BehaviorSubject<String>.seeded('');
            BehaviorSubject<String> _confirmPassword =
                  BehaviorSubject<String>.seeded('');
            String _confirmPass;
            
            
            //sink
            void setPassword(String pass) =>
                _password.sink.add(pass);
            
            void setConfirmPassword(String confirmPass) =>
                  _confirmPassword.sink.add(confirmPass);
            
            //get
            String getPassword() => _password.value;
            String getConfirmPassword() => _confirmPassword.value;
            
            //streams
            Stream<String> get isPasswordValid$ =>
                  _password.stream.doOnData((event) {
                    if (event.isEmpty) {
                      _confirmPassword.addError("*");
                    }
                    if (getPassword() != event) {
                      if (event == _confirmPass) {
                        setConfirmPassword(_confirmPass);
                      } else {
                        _confirmPassword.addError("*");
                      }
                    }
                  });
            Stream<String> get isConfirmPasswordValid$ =>
                  _confirmPassword.stream.doOnData((event) {
                    if (event.isEmpty) {
                      _confirmPassword.addError("*");
                    }
                    if (getPassword() != event) {
                      _confirmPassword.addError("*");
                    }
                    if (getConfirmPassword != null) {
                      _confirmPass = event;
                    }
                  });
            
            Stream<bool> get isPasswordAndConfirmPasswordValid$ => CombineLatestStream(
                  [isPasswordValid$, isConfirmPasswordValid$],
                  (value) => true);
    
            void dispose()
            {
               _Password?.close();
               _confirmPassword?.close();
            }
}