将 StreamController<String>.broadcast() 更改为 BehaviorSubject<String>() 后按钮保持禁用状态
Button stays disabled after changing StreamController<String>.broadcast() to BehaviorSubject<String>()
我使用 Streams 和 rxdart 进行表单验证。当我使用 StreamController<String>.broadcast()
时,按钮启用-禁用逻辑工作正常。
即使逻辑正确,将其更改为 BehaviorSubject<String>()
按钮仍处于禁用状态。
bloc.dart
import 'dart:async';
import 'package:login_validation_with_bloc/blocs/validator.dart';
import 'package:rxdart/rxdart.dart';
class Bloc with Validator {
final _emailController = StreamController<String>.broadcast();
final _passwordController = StreamController<String>.broadcast();
Stream<String> get email => _emailController.stream.transform(validateEmail);
Stream<String> get password =>
_passwordController.stream.transform(validatePassword);
Stream<bool> get validForm =>
Observable.combineLatest2(email, password, (e, p) => true);
Function(String) get changeEmail => _emailController.sink.add;
Function(String) get changePassword => _passwordController.sink.add;
dispose() {
_emailController.close();
_passwordController.close();
}
}
final bloc = Bloc();
home.dart,两个文本字段和提交按钮
Widget emailTextField(context, Bloc bloc) => StreamBuilder(
stream: bloc.email,
builder: (context, snapshot) => TextField(
decoration: InputDecoration(
labelText: "Email",
hintText: "Enter your email address",
errorText: snapshot.error,
border: UnderlineInputBorder()),
keyboardType: TextInputType.emailAddress,
onChanged: bloc.changeEmail,
),
);
Widget passwordTextField(context, Bloc bloc) => StreamBuilder(
stream: bloc.password,
builder: (context, snapshot) => TextField(
decoration: InputDecoration(
labelText: "Password",
hintText: "Enter your password",
errorText: snapshot.error,
border: UnderlineInputBorder()),
keyboardType: TextInputType.text,
obscureText: true,
onChanged: bloc.changePassword,
),
);
Widget submitButton(context, Bloc bloc) => StreamBuilder(
stream: bloc.validForm,
builder: (context, snapshot) {
return Container(
child: RaisedButton(
color: Colors.blue,
disabledColor: Colors.grey,
textColor: Colors.white,
disabledTextColor: Colors.white70,
onPressed: snapshot.hasData && !snapshot.hasError
? () {
print("Submit button pressed");
}
: null,
elevation: 5,
disabledElevation: 0,
child: Text("Submit"),
),
);
},
);
变化
在bloc.dart
final _emailController = BehaviorSubject<String>();
final _passwordController = BehaviorSubject<String>();
submit() {
final validEmail = _emailController.value;
final validPassword = _passwordController.value;
print("\n\tEmail: $validEmail\n\tPassword: $validPassword");
}
在home.dart
snapshot.hasData && !snapshot.hasError ? bloc.submit() : null,
我希望按钮在逻辑正确时保持启用状态,并且在按下按钮之前不应调用该方法
在home.dart中:
改变这个:
snapshot.hasData && !snapshot.hasError ? bloc.submit() : null,
至此
snapshot.hasData && !snapshot.hasError ? bloc.submit : null,
解释:
bloc.submit
指的是方法,bloc.submit()
指的是该方法的 return 值。
您所做的是您指的是该方法的 return 值,因为您没有 return 该方法正在执行的任何事情,而是作为值 returned 为空,按钮仍处于禁用状态。
我使用 Streams 和 rxdart 进行表单验证。当我使用 StreamController<String>.broadcast()
时,按钮启用-禁用逻辑工作正常。
即使逻辑正确,将其更改为 BehaviorSubject<String>()
按钮仍处于禁用状态。
bloc.dart
import 'dart:async';
import 'package:login_validation_with_bloc/blocs/validator.dart';
import 'package:rxdart/rxdart.dart';
class Bloc with Validator {
final _emailController = StreamController<String>.broadcast();
final _passwordController = StreamController<String>.broadcast();
Stream<String> get email => _emailController.stream.transform(validateEmail);
Stream<String> get password =>
_passwordController.stream.transform(validatePassword);
Stream<bool> get validForm =>
Observable.combineLatest2(email, password, (e, p) => true);
Function(String) get changeEmail => _emailController.sink.add;
Function(String) get changePassword => _passwordController.sink.add;
dispose() {
_emailController.close();
_passwordController.close();
}
}
final bloc = Bloc();
home.dart,两个文本字段和提交按钮
Widget emailTextField(context, Bloc bloc) => StreamBuilder(
stream: bloc.email,
builder: (context, snapshot) => TextField(
decoration: InputDecoration(
labelText: "Email",
hintText: "Enter your email address",
errorText: snapshot.error,
border: UnderlineInputBorder()),
keyboardType: TextInputType.emailAddress,
onChanged: bloc.changeEmail,
),
);
Widget passwordTextField(context, Bloc bloc) => StreamBuilder(
stream: bloc.password,
builder: (context, snapshot) => TextField(
decoration: InputDecoration(
labelText: "Password",
hintText: "Enter your password",
errorText: snapshot.error,
border: UnderlineInputBorder()),
keyboardType: TextInputType.text,
obscureText: true,
onChanged: bloc.changePassword,
),
);
Widget submitButton(context, Bloc bloc) => StreamBuilder(
stream: bloc.validForm,
builder: (context, snapshot) {
return Container(
child: RaisedButton(
color: Colors.blue,
disabledColor: Colors.grey,
textColor: Colors.white,
disabledTextColor: Colors.white70,
onPressed: snapshot.hasData && !snapshot.hasError
? () {
print("Submit button pressed");
}
: null,
elevation: 5,
disabledElevation: 0,
child: Text("Submit"),
),
);
},
);
变化
在bloc.dart
final _emailController = BehaviorSubject<String>();
final _passwordController = BehaviorSubject<String>();
submit() {
final validEmail = _emailController.value;
final validPassword = _passwordController.value;
print("\n\tEmail: $validEmail\n\tPassword: $validPassword");
}
在home.dart
snapshot.hasData && !snapshot.hasError ? bloc.submit() : null,
我希望按钮在逻辑正确时保持启用状态,并且在按下按钮之前不应调用该方法
在home.dart中:
改变这个:
snapshot.hasData && !snapshot.hasError ? bloc.submit() : null,
至此
snapshot.hasData && !snapshot.hasError ? bloc.submit : null,
解释:
bloc.submit
指的是方法,bloc.submit()
指的是该方法的 return 值。
您所做的是您指的是该方法的 return 值,因为您没有 return 该方法正在执行的任何事情,而是作为值 returned 为空,按钮仍处于禁用状态。