Flutter 颤振-流错误未持续(使用块模式)

Flutter 颤振-流错误未持续(使用块模式),flutter,dart,stream,Flutter,Dart,Stream,因此,我尝试使用streams和bloc模式在Flatter中创建一个注册表单 问题是,为my streams添加到接收器的错误似乎不会持续存在 提交有效的GETER似乎不考虑添加到PuxWordRype流中的错误,这会导致登录按钮在不应该时被点击。 复制步骤: 填写一封有效的电子邮件 填写有效密码(密码字段) 填写有效密码(密码重新键入字段) 从“重新键入”字段中删除所有内容 删除密码字段中的所有内容 在“密码”字段中键入有效密码,即使“重新键入”字段为空,登录按钮仍显示为可单击 这是我的

因此,我尝试使用streams和bloc模式在Flatter中创建一个注册表单

问题是,为my streams添加到接收器的错误似乎不会持续存在

提交有效的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);
      },
    );
  }