#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");
}
});
Приветствую, Мариано