在登录视图中,如果用户在未插入其凭据的情况下轻按了登录按钮,则LoginFailState为yield,视图对此做出反应。如果他再次点击,则该LoginFailstate再次变为yield,但是视图对此没有反应。那么,有没有办法产生相同状态更多的时间?
有一些代码可以更好地解释我的情况:
class LoginBloc extends Bloc<LoginEvent, LoginState> {
@override
LoginState get initialState => LoginUninitialized();
@override
Stream<LoginState> mapEventToState(LoginEvent event) {
if (event is loginButtonPressed) {
yield LoginFailState();
}
}
查看:
@override
Widget build(BuildContext context) {
return BlocBuilder(
bloc: _loginBloc,
builder: (BuildContext context, LoginState state) {
if (state is LoginFail) {
print ('Login fail');
}
return Column(
...
)
答案 0 :(得分:1)
默认情况下,当相同状态一个接一个地传递时,默认BLoC模式将不会发出状态。一种方法是通过LoginFailState
后再传递您的初始BLoC状态。
因此,在用户使用错误的凭据单击按钮之后,传递的状态将不会是:
LoginFailState()
LoginFailState()
但是
LoginFailState()
LoginEmptyState()
LoginFailState()
LoginEmptyState()
这将使UI对他们每个人做出反应。
但是我认为最好,最干净的解决方案是在通过LoadingState
之前先从BLoC传递LoginFailState()
。
您可以遵循我最近写的关于该主题的blog post。
答案 1 :(得分:0)
使用 BlocListener 对状态更改做出反应。
BlocListener(
bloc: _loginBloc,
listener: (BuildContext context, LoginState state) {
if (state is LoginFail) {
print('Login failed');
// Or show a Snackbar
}
},
child: BlocBuilder(
bloc: _loginBloc,
builder: (BuildContext context, LoginState state){
// Your display code here
return Container();
},
),
)
答案 2 :(得分:0)
如果您不扩展Equitable,或者实现使两个LoginFailState相等的自己的'=='逻辑,则可以收到“相同”状态的更新。
解决方案是在两者之间产生不同的状态,就像Bloc示例一样。
yield LoginLoading();
每次登录按钮点击都会调用它。 Felangel's LoginBloc example.
答案 3 :(得分:0)
如果您使用Equitable并尝试发出具有不同属性的同一State的两个相等实例,请确保您覆盖props
数组。通过覆盖props
数组,Equitable将知道如何比较状态实例。
class TablesLoadedState extends Equatable {
final List<TableEntity> tablesList;
TablesLoadedState(this.tablesList);
@override
List<Object> get props => [tablesList];
}
因此,当bloc发出具有不同值的相同状态的两个实例时,这些状态实例将传递给BlocListener,并且UI将根据新数据进行更新。