Flutter — Block — проблема со сравнением двух текстовых полей password и passwordConfirm

#flutter #mobile #bloc

#флаттер #Мобильный #блок

Вопрос:

Я начинающий флаттер. Я использую Bloc и смог проверить отдельные текстовые поля, но у меня возникли некоторые сомнения при попытке сравнить два текстовых поля (password и passwordConfirm). Я использую BehaviorSubject() в качестве контроллера и Rx.dart, но я не могу найти способ связать их. Я также пытался использовать StreamTransformer, но не смог ввести более одного значения.

 final validatePasswordConfirm = StreamTransformer<String,String>
   .fromHandlers(handleData: (passwordConfirm, sink) {});
  

Вот остальной код (часть register_page.dart, register_bloc.dart и validators.dart):

 // register_page.dart
    
Widget create_password(RegisterBloc bloc){
        return StreamBuilder(
            stream: bloc.passwordStream,
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              return Container(
                padding: EdgeInsets.symmetric(horizontal: 20.0),
                child: TextField(
                  obscureText: true,
                  decoration: InputDecoration(
                      icon: Icon(Icons.lock, color: Colors.deepPurple),
                      labelText: 'password',
                      counterText: snapshot.data,
                      errorText: snapshot.error
                  ),
                  onChanged: (value) => bloc.changePassword(value),
                ),
              );
            },
         );
      }
    
      Widget create_password_confirm(RegisterBloc bloc){
        return StreamBuilder(
          stream: bloc.validatePasswordConfirmStream,
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            return Container(
              padding: EdgeInsets.symmetric(horizontal: 20.0),
              child: TextField(
                obscureText: true,
                decoration: InputDecoration(
                    icon: Icon(Icons.lock, color: Colors.deepPurple),
                    labelText: 'password Confirm',
                    counterText: snapshot.data,
                    errorText: snapshot.error
                ),
                onChanged: (value) => bloc.changePasswordConfirm(value),
              ),
            );
          },
        );
      }
  
     // register_bloc.dart
    class RegisterBloc with Validators{
    
      final _usernameController = BehaviorSubject<String>();
      final _emailController = BehaviorSubject<String>();
      final _passwordController = BehaviorSubject<String>();
      final _passwordConfirmController = BehaviorSubject<String>();
    
    
      Stream<String> get usernameStream => _emailController.stream.transform(validatePassword);
      Stream<String> get emailStream => _emailController.stream.transform(validateEmail);
      Stream<String> get passwordStream => _passwordController.stream.transform(validatePassword);
      Stream<String> get passwordConfirmStream => _passwordConfirmController.stream.transform(validatePasswordConfirm);
    
    
      Stream<String> get validatePasswordConfirmStream => Rx.combineLatest2(passwordStream, passwordConfirmStream,
              (p, pc){
            return p.compareTo(pc)? p.passwordStream:'passwords does not match';
          });
    
      Stream<bool> get formValidStream =>
          Rx.combineLatest4(usernameStream, emailStream, passwordStream, passwordConfirmStream, (u,e,p, pc) => true);
    
      Function(String) get changeUsername => _usernameController.sink.add;
      Function(String) get changeEmail => _emailController.sink.add;
      Function(String) get changePassword => _passwordController.sink.add;
      Function(String) get changePasswordConfirm => _passwordConfirmController.sink.add;
    
    
      String get username => _usernameController.value;
      String get email => _emailController.value;
      String get password => _passwordController.value;
      String get passwordConfirm => _passwordController.value;
    
      dispose() {
        _usernameController?.close();
        _emailController?.close();
        _passwordController?.close();
        _passwordConfirmController?.close();
      }
    }
  
     // validators.dart
    class Validators{
      final validateEmail = StreamTransformer<String,String>.fromHandlers(
          handleData: (email, sink) {
            Pattern pattern = r'^(([^<>()[]\.,;:s@"] (.[^<>()[]\.,;:s@"] )*)|(". "))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9] .) [a-zA-Z]{2,}))$';
            RegExp regExp = new RegExp(pattern);
            if (regExp.hasMatch(email)) {
              sink.add(email);
            } else {
              sink.addError('Email no es correcto');
            }
          }
      );
    
      final validatePassword = StreamTransformer<String,String>.fromHandlers(
        handleData: (p, sink){
          if(p.length >= 6) {
            sink.add(p);
          } else {
            sink.addError('Más de 6 caracteres por favor');
          }
        }
      );
    
      final validatePasswordConfirm = StreamTransformer<String,String>.fromHandlers(
          handleData: (passwordConfirm, sink) {});
    }
  

Заранее спасибо и извините за мой плохой английский.
Приветствую, Мариано

Ответ №1:

Наконец, через несколько часов я смог найти ответ на свой вопрос. Теперь я могу сравнить два текстовых поля, и если они не совпадают друг с другом, я отправлю в passwordConfirm TextField сообщение об ошибке.

 Stream<String> get passwordConfirmStream => _passwordConfirmController.stream
      .transform(validatePassword).doOnData((String c){
    if (0 != _passwordController.value.compareTo(c)){
      _passwordConfirmController.addError("No Match");
    }
  }); 
  

Приветствую, Мариано