Flutter 颤振-流错误未持续(使用块模式)
因此,我尝试使用streams和bloc模式在Flatter中创建一个注册表单 问题是,为my streams添加到接收器的错误似乎不会持续存在Flutter 颤振-流错误未持续(使用块模式),flutter,dart,stream,Flutter,Dart,Stream,因此,我尝试使用streams和bloc模式在Flatter中创建一个注册表单 问题是,为my streams添加到接收器的错误似乎不会持续存在 提交有效的GETER似乎不考虑添加到PuxWordRype流中的错误,这会导致登录按钮在不应该时被点击。 复制步骤: 填写一封有效的电子邮件 填写有效密码(密码字段) 填写有效密码(密码重新键入字段) 从“重新键入”字段中删除所有内容 删除密码字段中的所有内容 在“密码”字段中键入有效密码,即使“重新键入”字段为空,登录按钮仍显示为可单击 这是我的
提交有效的GETER似乎不考虑添加到PuxWordRype流中的错误,这会导致登录按钮在不应该
时被点击。 复制步骤:- 填写一封有效的电子邮件
- 填写有效密码(密码字段)
- 填写有效密码(密码重新键入字段)
- 从“重新键入”字段中删除所有内容
- 删除密码字段中的所有内容
- 在“密码”字段中键入有效密码,即使“重新键入”字段为空,登录按钮仍显示为可单击
导入'dart:async';
导入“包:firebase_auth/firebase_auth.dart”;
导入“validators.dart”;
导入“dart:io”;
导入“包:rxdart/rxdart.dart”;
类Bloc使用验证器扩展对象{
最终电子邮件=行为主体();
最终密码=行为主体();
final _passwordretype=BehaviorSubject();
最终的_isSignedIn=行为主体();
//向流中添加数据
Stream get email=>\u email.Stream.transform(validateEmail);
Stream get password=>\u password.Stream.transform(validatePassword);
Stream get passwordretype=>\u passwordretype.Stream.transform(validatePasswordRetype)
.doOnData((字符串c){
如果(0!=_password.value.compareTo(c)){
_passwordretype.addError(“密码不匹配”);
}
});
Stream get signInStatus=>\u isSignedIn.Stream;
流获取submitValid=>
Rx.combineLatest3(电子邮件、密码、密码类型,(e、p、r)=>true);
//更改数据
函数(字符串)get changemail=>\u email.sink.add;
函数(字符串)get changePassword=>\u password.sink.add;
函数(字符串)get-changePasswordRetype=>\u-passwordretype.sink.add;
函数(bool)get showProgressBar=>\u isSignedIn.add;
寄存器()异步{
final FirebaseAuth _auth=FirebaseAuth.instance;
试一试{
showProgressBar(真);
最终FirebaseUser用户=(等待_auth.createUserWithEmailAndPassword(
电子邮件:_email.value,
密码:_password.value,
))
.用户;
如果(用户!=null){
//设置状态(){
//_成功=正确;
//_userEmail=user.email;
//Navigator.of(context.pushName和removeUntil)(
//“/home”,(路由)=>false);
//
////Navigator.of(context.pushReplacementNamed('/home');
//
// });
}否则{
//Scaffold.of(上下文).showSnackBar(SnackBar(
//内容:文本(“发生错误,请稍后再试”),
// ));
//_成功=错误;
}
}捕捉(错误){
_isSignedIn.加法器(err);
打印(错误);
//设置状态(){
//_showLoading=假;
//_error=true;
// });
}
}
处置{
_email.drain();
_email.close();
_password.drain();
_password.close();
_passwordretype.drain();
_passwordretype.close();
}
}
屏幕上的标记。省道
import'package:firebase_auth/firebase_auth.dart';
进口“包装:颤振/材料.省道”;
导入“package:lendy/src/blocs/bloc.dart”;
导入“package:lendy/src/blocs/provider.dart”;
类SignupScreen扩展了无状态小部件{
//最终的GlobalKey _formKey=GlobalKey();
//final TextEditingController_emailController=TextEditingController();
//最终文本编辑控制器_passwordController=文本编辑控制器();
//最终文本编辑控制器_passwordController2=文本编辑控制器();
final FirebaseAuth _auth=FirebaseAuth.instance;
//最终GoogleSignIn _GoogleSignIn=GoogleSignIn();
字符串_userID=“”;
成功;
字符串_userEmail;
@凌驾
小部件构建(构建上下文){
final bloc=Provider.of(上下文);
返回脚手架(
appBar:appBar(
标题:文本(“注册”),
),
主体:容器(
子:列(
儿童:[
emailField(集团),
密码字段(集团),
passwordFieldRe(集团),
大小盒子(
身高:10.0,
),
按钮(组)
],
),
),
);
}
Widget emailField(Bloc-Bloc){
返回流生成器(
流:bloc.email,
生成器:(上下文,快照){
返回文本字段(
onChanged:bloc.changemail,
键盘类型:TextInputType.emailAddress,
装饰:输入装饰(
hintText:'输入电子邮件地址',
labelText:“电子邮件地址”,
errorText:snapshot.error),
);
},
);
}
小部件密码字段(Bloc-Bloc){
返回流生成器(
流:bloc.password,
生成器:(上下文,快照){
返回文本字段(
onChanged:bloc.changePassword,
装饰:输入装饰(
hintText:“输入密码”,
labelText:“密码”,
errorText:snapshot.error),
);
});
}
Widget密码字段re(Bloc-Bloc){
返回流生成器(
流:bloc.passwordretype,
生成器:(上下文,快照){
返回文本字段(
onChanged:bloc.changePasswordRetype,
装饰:输入装饰(
hintText:“重新键入密码”,
labelText:“密码”,
errorText:snapshot.error),
);
});
}
小部件按钮(Bloc-Bloc){
返回流生成器(
流:bloc.submitValid,
生成器:(上下文,快照){
返回上升按钮(
子:文本(‘寄存器’),
颜色:颜色,蓝色,
//如果是真的
onPressed:snapshot.hasData
? () {
//bloc.showProgressBar(真实);
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'validators.dart';
import 'dart:io';
import 'package:rxdart/rxdart.dart';
class Bloc extends Object with Validators {
final _email = BehaviorSubject<String>();
final _password = BehaviorSubject<String>();
final _passwordretype = BehaviorSubject<String>();
final _isSignedIn = BehaviorSubject<bool>();
//Add data to stream
Stream<String> get email => _email.stream.transform(validateEmail);
Stream<String> get password => _password.stream.transform(validatePassword);
Stream<String> get passwordretype=> _passwordretype.stream.transform(validatePasswordRetype)
.doOnData((String c){
if(0 != _password.value.compareTo(c)){
_passwordretype.addError("Passwords do not match");
}
});
Stream<bool> get signInStatus => _isSignedIn.stream;
Stream<bool> get submitValid =>
Rx.combineLatest3(email, password, passwordretype, (e, p, r) => true);
//Change data
Function(String) get changeEmail => _email.sink.add;
Function(String) get changePassword => _password.sink.add;
Function(String) get changePasswordRetype => _passwordretype.sink.add;
Function(bool) get showProgressBar => _isSignedIn.add;
register() async {
final FirebaseAuth _auth = FirebaseAuth.instance;
try {
showProgressBar(true);
final FirebaseUser user = (await _auth.createUserWithEmailAndPassword(
email: _email.value,
password: _password.value,
))
.user;
if (user != null) {
// setState(() {
// _success = true;
// _userEmail = user.email;
// Navigator.of(context).pushNamedAndRemoveUntil(
// '/home', (Route<dynamic> route) => false);
//
//// Navigator.of(context).pushReplacementNamed('/home');
//
// });
} else {
// Scaffold.of(context).showSnackBar(SnackBar(
// content: Text("Error occured, please try again later"),
// ));
// _success = false;
}
} catch (err) {
_isSignedIn.addError(err);
print(err);
// setState(() {
// _showLoading = false;
// _error = true;
// });
}
}
dispose() {
_email.drain();
_email.close();
_password.drain();
_password.close();
_passwordretype.drain();
_passwordretype.close();
}
}
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:lendy/src/blocs/bloc.dart';
import 'package:lendy/src/blocs/provider.dart';
class SignupScreen extends StatelessWidget {
// final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
// final TextEditingController _emailController = TextEditingController();
// final TextEditingController _passwordController = TextEditingController();
// final TextEditingController _passwordController2 = TextEditingController();
final FirebaseAuth _auth = FirebaseAuth.instance;
// final GoogleSignIn _googleSignIn = GoogleSignIn();
String _userID = "";
bool _success;
String _userEmail;
@override
Widget build(BuildContext context) {
final bloc = Provider.of(context);
return Scaffold(
appBar: AppBar(
title: Text("Signup"),
),
body: Container(
child: Column(
children: <Widget>[
emailField(bloc),
passwordField(bloc),
passwordFieldRe(bloc),
SizedBox(
height: 10.0,
),
button(bloc)
],
),
),
);
}
Widget emailField(Bloc bloc) {
return StreamBuilder(
stream: bloc.email,
builder: (context, snapshot) {
return TextField(
onChanged: bloc.changeEmail,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
hintText: 'Enter email address',
labelText: 'Email-address',
errorText: snapshot.error),
);
},
);
}
Widget passwordField(Bloc bloc) {
return StreamBuilder(
stream: bloc.password,
builder: (context, snapshot) {
return TextField(
onChanged: bloc.changePassword,
decoration: InputDecoration(
hintText: 'Enter password',
labelText: 'Password',
errorText: snapshot.error),
);
});
}
Widget passwordFieldRe(Bloc bloc) {
return StreamBuilder(
stream: bloc.passwordretype,
builder: (context, snapshot) {
return TextField(
onChanged: bloc.changePasswordRetype,
decoration: InputDecoration(
hintText: 'Retype password',
labelText: 'Password',
errorText: snapshot.error),
);
});
}
Widget button(Bloc bloc) {
return StreamBuilder(
stream: bloc.submitValid,
builder: (context, snapshot) {
return RaisedButton(
child: Text('Register'),
color: Colors.blue,
//if true
onPressed: snapshot.hasData
? () {
// bloc.showProgressBar(true);
bloc.register();
}
: null);
},
);
}
Widget buttons(Bloc bloc) {
return StreamBuilder(
stream: bloc.submitValid,
builder: (context, snapshot1) {
return StreamBuilder(
stream: bloc.signInStatus,
builder: (context, snapshot2) {
if (!snapshot2.hasData || snapshot2.hasError) {
return Column(
children: <Widget>[
RaisedButton(
child: Text('Register'),
color: Colors.blue,
onPressed: snapshot1.hasData
? () {
bloc.register();
}
: null,
),
snapshot2.hasError ? Text("ee") : Container()
],
);
} else {
return CircularProgressIndicator();
}
},
);
},
);
}
Widget submitButton(Bloc bloc) {
return StreamBuilder(
stream: bloc.signInStatus,
builder: (context, snapshot) {
if (snapshot.hasError || !snapshot.hasData) {
return buttons(bloc);
} else {
return CircularProgressIndicator();
}
});
}
/
import 'dart:async';
class Validators {
final validateEmail = StreamTransformer<String, String>.fromHandlers(
handleData: (email, sink){
if (RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(email)){
sink.add(email);
} else {
sink.addError('Please enter a valid email address.');
}
}
);
final validatePassword = StreamTransformer<String, String>.fromHandlers(
handleData: (password, sink){
if (password.length > 3){
sink.add(password);
} else {
sink.addError('Password is too short.');
}
}
);
final validatePasswordRetype = StreamTransformer<String, String>.fromHandlers(
handleData: (password, sink){
print("HANDLE DATA");
if (password.length > 3){
sink.add(password);
} else {
sink.addError('Password is too short.');
}
}
);
}
Stream<bool> get submitValid =>
Rx.combineLatest3(email, password, passwordretype, (e, p, r) {
if (p == _password.value && r == _passwordretype.value){
return true;
} else {
return false;
}
});
Widget button(Bloc bloc) {
return StreamBuilder(
stream: bloc.submitValid,
builder: (context, snapshot) {
return RaisedButton(
child: Text('Register'),
color: Colors.blue,
onPressed: snapshot.hasData && snapshot.data
? () {
bloc.register();
}
: null);
},
);
}