[英]How to pass Stream<String> values as parameters to a function created in a bloc file FLUTTER
I have a login bloc file where I have created 2 streams username and password我有一个登录块文件,其中创建了 2 个流用户名和密码
class LoginBloc {
LoginRepository _loginRepository = new LoginRepository();
StreamController _loginController = StreamController<Response<LoginModel>>();
//declare streams
final _userName = BehaviorSubject<String>();
final _password = BehaviorSubject<String>();
//get data from streams
StreamSink<Response<LoginModel>> get loginControllerSink =>
_loginController.sink;
Stream<String> get loginUserName => _userName.stream;
Stream<String> get loginPassword => _password.stream;
Stream<bool> get submitLoginForm =>
Rx.combineLatest2(loginUserName, loginPassword, (a, b) => true);
Function(String) get changeLoginUserName => _userName.sink.add;
Function(String) get changeLoginPassword => _password.sink.add;
//dispose
dispose() {
_userName.close();
_password.close();
}
//functions
login(email, password, context) async {
try {
LoginModel data = await _loginRepository.loginIntoSystem(email, password);
loginControllerSink.add(Response.completed(data));
Navigator.pushNamed(context, '/dashboard');
} catch (e) {
loginControllerSink.add(Response.error(e.toString()));
print(e);
}
}
}
Here's the login.dart这是登录名。dart
class Login extends StatefulWidget {
@override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
bool _passwordVisible = false;
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
final LoginBloc bloc = LoginProvider.of(context);
return Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: SafeArea(
child: Center(
child:
Column(
children: <Widget>[
SizedBox(height: size.height*0.05),
Icon(
Icons.track_changes,
size: size.width*0.06,
),
SizedBox(height: size.height*0.02),
Text('Login',
style: TextStyle(
color: Color(0xff005D6C),
fontSize: size.width*0.02,
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic)),
SizedBox(height: size.height*0.04),
Container(
width: size.width * 0.2,
padding: EdgeInsets.only(bottom: 20.0),
child: StreamBuilder<String>(
stream: bloc.loginUserName,
builder: (context, snapshot) {
return TextField(
onChanged: bloc.changeLoginUserName,
decoration: new InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 15.0),
border: new OutlineInputBorder(
borderSide: const BorderSide(
width: 2.0, style: BorderStyle.solid),
borderRadius: BorderRadius.circular(50.0)),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Colors.grey, width: 2.0),
borderRadius: BorderRadius.circular(50.0),
),
hintText: 'User Name',
hintStyle: new TextStyle(
color: Colors.grey,
fontWeight: FontWeight.bold),
suffixIcon: const Icon(
Icons.person,
size: 30.0,
color: Colors.grey,
),
errorText: snapshot.error),
);
}),
),
Container(
width: size.width * 0.2,
padding: EdgeInsets.only(bottom: 20.0),
child: StreamBuilder<String>(
stream: bloc.loginPassword,
builder: (context, snapshot) {
return TextField(
onChanged: bloc.changeLoginPassword,
obscureText: !_passwordVisible,
maxLength: 20,
decoration: new InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 15.0),
border: new OutlineInputBorder(
borderSide: const BorderSide(
width: 2.0, style: BorderStyle.solid),
borderRadius: BorderRadius.circular(50.0)),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Colors.grey, width: 2.0),
borderRadius: BorderRadius.circular(50.0),
),
hintText: 'Password',
hintStyle: new TextStyle(
color: Colors.grey,
fontWeight: FontWeight.bold),
prefixIcon: const Icon(
Icons.lock,
size: 30.0,
color: Colors.grey,
),
suffixIcon: IconButton(
icon: Icon(
// Based on passwordVisible state choose the icon
_passwordVisible
? Icons.visibility
: Icons.visibility_off,
color: Colors.grey,
),
onPressed: () {
setState(() {
_passwordVisible = !_passwordVisible;
});
},
),
errorText: snapshot.error),
);
}),
),
Container(
width: size.width * 0.2,
child: ClipRRect(
borderRadius: BorderRadius.circular(29),
child: StreamBuilder<bool>(
stream: bloc.submitLoginForm,
builder: (context, snapshot){
return FlatButton(
color: Color(0XFFEFEFEF),
textColor: primaryColor,
disabledColor: Colors.grey,
disabledTextColor: Colors.black,
padding: EdgeInsets.symmetric(
vertical: 12.0, horizontal: 10.0),
onPressed: () => snapshot.hasError ? null : bloc.login(bloc.loginUserName, bloc.loginPassword, context) ,
child: Text(
"Login",
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic),
),
);
},
),
),
)
],
)
),
),
),
);
}
}
I am calling the login function on CLick of login button and passing the username, password and context as parameters.我在登录按钮的 CLick 上调用登录 function 并将用户名、密码和上下文作为参数传递。 But on click its giving "Expected a value of type 'String', but got one of type 'BehaviorSubject'"
但是点击它给出“期望'String'类型的值,但得到'BehaviorSubject'类型之一”
added the loginIntoSystem:添加了 loginIntoSystem:
Future<LoginModel> loginIntoSystem(String email, String password)
async {
dynamic body = {
'email': email,
'password': password
};
final response = await _provider.post("/login", body);
return LoginModel.fromJson(response);
}
Is there a way to convert BehaviorSubject to String?有没有办法将 BehaviorSubject 转换为字符串?
I found the solution.我找到了解决方案。
By using value property, I was able to get the values.通过使用 value 属性,我能够获取值。
final fEmail = _email.value;
final fPassword = _password.value;
Thank you everyone for taking your time and posting the answers.感谢大家抽出宝贵的时间并发布答案。
You are right.你说的对。 I was wrong, and behavior subject has a property
value
which returns value of that behavior subject.我错了,行为主体有一个属性
value
,它返回该行为主体的值。 You can use this to get the email and password out of your behavior subject.您可以使用它从您的行为主题中获取 email 和密码。 Also, since your bloc file already has access to those variables, you don't have to pass them as arguments from your onPressed function.
此外,由于您的 bloc 文件已经可以访问这些变量,因此您不必将它们作为 arguments 从您的 onPressed function 传递。
login(context) async {
final email = _userName.value;
final password = _password.value;
try {
LoginModel data = await _loginRepository.loginIntoSystem(email, password);
loginControllerSink.add(Response.completed(data));
Navigator.pushNamed(context, '/dashboard');
} catch (e) {
loginControllerSink.add(Response.error(e.toString()));
print(e);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.