- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在尝试在包含登录和注册的基本身份验证表单上使用 BLOC 模式,其中登录和注册之间的唯一区别是注册有一个额外的 Confirm Password
字段,这也有助于是否应启用 Signup
按钮。
我有两个问题:1.这是个问题。目前,如果我输入一些通过 Login
验证的登录名,然后切换到 Signup
表单,则启用 Signup
按钮,这是错误的,因为 Confirm Password
仍然是空的。如何解决这个问题?2. 我觉得有比我所做的更好的方法来实现 Confirm Password
验证和 Signup
按钮验证。我最初尝试为 Confirm Password
创建一个验证器,但它应该将 both 密码和确认密码作为输入,但无法使其作为 StreamTransformer
只带一个入参。执行此操作的更好方法是什么?
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:rxdart/rxdart.dart';
void main() => runApp(AuthProvider(child: MaterialApp(home: Auth())));
enum AuthMode { Signup, Login }
class Auth extends StatefulWidget {
@override
_AuthState createState() => _AuthState();
}
class _AuthState extends State<Auth> {
AuthMode authMode = AuthMode.Login;
bool get _isLoginMode => authMode == AuthMode.Login;
TextEditingController confirmPasswordCtrl = TextEditingController();
@override
Widget build(BuildContext context) {
final bloc = AuthProvider.of(context);
return Scaffold(
body: Container(
margin: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
emailField(bloc),
passwordField(bloc),
confirmPasswordField(bloc),
Container(
margin: EdgeInsets.only(top: 40.0),
),
FlatButton(
child: Text('Switch to ${_isLoginMode ? 'Signup' : 'Login'}'),
onPressed: swithAuthMode,
),
loginOrSignupButton(bloc),
],
),
),
);
}
void swithAuthMode() {
setState(() {
authMode = authMode == AuthMode.Login ? AuthMode.Signup : AuthMode.Login;
});
}
Widget confirmPasswordField(AuthBloc bloc) {
return _isLoginMode
? Container()
: StreamBuilder(
stream: bloc.passwordConfirmed,
builder: (context, snapshot) {
return TextField(
obscureText: true,
onChanged: bloc.changeConfirmPassword,
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'Confirm Password',
errorText: snapshot.hasData && !snapshot.data ? 'password mismatch' : null,
),
);
},
);
}
Widget emailField(AuthBloc bloc) {
return StreamBuilder(
stream: bloc.email,
builder: (context, snapshot) {
return TextField(
keyboardType: TextInputType.emailAddress,
onChanged: bloc.changeEmail,
decoration: InputDecoration(
hintText: 'your email',
labelText: 'Email',
errorText: snapshot.error,
),
);
},
);
}
Widget loginOrSignupButton(AuthBloc bloc) {
return StreamBuilder(
stream: _isLoginMode ? bloc.submitValid : bloc.signupValid,
builder: (context, snapshot) {
print('hasData: ${snapshot.hasData}, data: ${snapshot.data}');
return RaisedButton(
onPressed: // The problem is, after entering some login details then switching from login to signup, the Signup button is enabled.
!snapshot.hasData || !snapshot.data ? null : () => onSubmitPressed(bloc, context),
color: Colors.blue,
child: Text('${_isLoginMode ? 'Log in' : 'Sign up'}'),
);
},
);
}
void onSubmitPressed(AuthBloc bloc, BuildContext context) async {
var response = await bloc.submit(_isLoginMode);
if (response.success) {
Navigator.pushReplacementNamed(context, '/home');
} else {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Error'),
content: Text(response.message),
actions: <Widget>[
FlatButton(
child: Text('Ok'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
});
}
}
Widget passwordField(AuthBloc bloc) {
return StreamBuilder(
stream: bloc.password,
builder: (_, snapshot) {
return TextField(
obscureText: true,
onChanged: bloc.changePassword,
decoration: InputDecoration(
labelText: 'Password',
errorText: snapshot.error,
hintText: 'at least 6 characters',
),
);
},
);
}
}
class AuthProvider extends InheritedWidget {
final bloc;
AuthProvider({Key key, Widget child}) :
bloc = AuthBloc(), super(key:key, child: child);
@override
bool updateShouldNotify(InheritedWidget oldWidget) => true;
static AuthBloc of(BuildContext context) => (context.inheritFromWidgetOfExactType(AuthProvider) as AuthProvider).bloc;
}
class Repository {
// this will call whatever backend to authenticate users.
Future<AuthResult> signupUser(String email, String password) => null;
Future<AuthResult> loginUser(String email, String password) => null;
}
class AuthBloc extends Object with AuthValidator {
final _emailController = BehaviorSubject<String>();
final _passwordController = BehaviorSubject<String>();
final _confirmPasswordController = BehaviorSubject<String>();
final _signupController = PublishSubject<Map<String, dynamic>>();
final Repository _repository = Repository();
Stream<String> get email => _emailController.stream.transform(validateEmail);
Stream<String> get password =>
_passwordController.stream.transform(validatePassword);
Stream<bool> get submitValid =>
Observable.combineLatest2(email, password, (e, p) => true);
// Is there a better way of doing passwordConfirmed and signupValid?
Stream<bool> get passwordConfirmed =>
Observable.combineLatest2(password, _confirmPasswordController.stream, (p, cp) => p == cp);
Stream<bool> get signupValid =>
Observable.combineLatest2(submitValid, passwordConfirmed, (s, p) => s && p);
// sink
Function(String) get changeEmail => _emailController.sink.add;
Function(String) get changePassword => _passwordController.sink.add;
Function(String) get changeConfirmPassword =>
_confirmPasswordController.sink.add;
Future<AuthResult> submit(bool isLogin) async {
final validEmail = _emailController.value;
final validPassword = _passwordController.value;
if (!isLogin)
return await _repository.signupUser(validEmail, validPassword);
return await _repository.loginUser(validEmail, validPassword);
}
void dispose() {
_emailController.close();
_passwordController.close();
_signupController.close();
_confirmPasswordController.close();
}
}
class AuthResult {
bool success;
String message;
AuthResult(this.success, this.message);
}
// demo validator
class AuthValidator {
final validateEmail = StreamTransformer<String, String>.fromHandlers(
handleData: (email, sink) {
if (email.contains('@')) sink.add(email);
else sink.addError('Email is not valid');
}
);
final validatePassword = StreamTransformer<String, String>.fromHandlers(
handleData: (password, sink) {
if (password.length >= 6) sink.add(password);
else sink.addError('Password must be at least 6 characters');
}
);
}
最佳答案
在您的情况下,执行 passwordConfirmed 的更好方法是:
Stream<String> get passwordConfirmed => _confirmPasswordController.stream
.transform(validatePassword).doOnData((String confirmPassword){
if(0 != _passwordController.value.compareTo(confirmPassword)){
_confirmPasswordController.addError("Passwords do not match");
}
});
根据 boeledi 建议 here .
关于flutter - 将 BLOC 模式用于身份验证表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52545188/
我正在使用SQL Server 2008 R2,并且想创建一个触发器。 对于每个添加(仅添加),将像这样更新一列: ABC-CurrentYear-AutoIncrementCode 例子: ABC-
是否可以在显示最终一致性的数据存储中创建/存储用户帐户? 似乎不可能在没有一堆架构复杂性的情况下管理帐户创建,以避免可能发生具有相同 UID(例如电子邮件地址)的两个帐户的情况? 最终一致性存储的用户
您好, 我有一个带有 Identity 的 .NetCore MVC APP并使用 this指导我能够创建自定义用户验证器。 public class UserDomainValidator : IU
这与以下问题相同:HiLo or identity? 我们以本站的数据库为例。 假设该站点具有以下表格: 帖子。 投票。 注释。 使用它的最佳策略是什么: 身份 - 这是更常见的。 或者 HiLo -
我想将 Blazor Server 与 ASP.NET Identity 一起使用。但我需要使用 PostgreSQL 作为用户/角色存储,因为它在 AWS 中。 它不使用 EF,这是我需要的。 我创
我正在开发一个 .NET 应用程序,它可以使用 Graph API 代表用户发送电子邮件。 提示用户对应用程序进行授权;然后使用获取的访问 token 来调用 Graph API。刷新 token 用
我使用 ASP.NET 身份和 ClaimsIdentity 来验证我的用户。当用户通过身份验证时,属性 User.Identity 包含一个 ClaimsIdentity 实例。 但是,在登录请求期
所以我在两台机器上都安装了 CYGWIN。 如果我这样做,它会起作用: ssh -i desktop_rsa root@remoteserver 这需要我输入密码 ssh root@remoteser
我尝试在 mac osx 上的终端中通过 telnet 连接到 TOR 并请求新身份,但它不起作用,我总是收到此错误消息: Trying 127.0.0.1... telnet: connect to
我正在开发一个 .NET 应用程序,它可以使用 Graph API 代表用户发送电子邮件。 提示用户对应用程序进行授权;然后使用获取的访问 token 来调用 Graph API。刷新 token 用
我正在开发一项服务,客户可以在其中注册他们的 webhook URL,我将发送有关已注册 URL 的更新。为了安全起见,我想让客户端(接收方)识别是我(服务器)向他们发送请求。 Facebook和 G
在 Haskell 中,有没有办法测试两个 IORef 是否相同?我正在寻找这样的东西: IORef a -> IORef a -> IO Bool 例如,如果您想可视化由 IORef 组成的图形,这
我是 .NET、MVC 和身份框架的新手。我注意到身份框架允许通过注释保护单个 Controller 操作。 [Authorize] public ActionResult Edit(int? Id)
我有一列具有身份的列,其计数为19546542,我想在删除所有数据后将其重置。我需要类似ms sql中的'dbcc checkident'这样的内容,但在Oracle中 最佳答案 在Oracle 12
这是我用来创建 session 以发送电子邮件的代码: props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enabl
我想了解 [AllowAnonymous] 标签的工作原理。 我有以下方法 [HttpGet] public ActionResult Add() { return View(); } 当我没
在使用沙盒测试环境时,PayPal 身份 token 对某些人显示而不对其他人显示的原因是否有任何原因。 我在英国使用 API,终生无法生成或找到 token 。 我已经遵循协议(protocol)并
我对非常简单的事情有一些疑问:IDENTITY。我尝试在 phpMyAdmin 中创建表: CREATE TABLE IF NOT EXISTS typEventu ( typEventu
习语 #1 和 #5 是 FinnAPL Idiom Library两者具有相同的名称:“Progressive index of (without replacement)”: ((⍴X)⍴⍋⍋X⍳
当我第一次在 TFS 中设置时,我的公司拼错了我的用户名。此后他们将其更改为正确的拼写,但该更改显然未反射(reflect)在 TFS 中。当我尝试 checkin 更改时,出现此错误: 有没有一种方
我是一名优秀的程序员,十分优秀!