我需要访问LoginBloc中的AuthenticationBloc,因此如果登录成功,则可以触发AuthenticationLogin()事件。到目前为止,我没有做任何事情。
我所做的:
class LoginBloc extends Bloc<LoginEvent, LoginState> {
final AuthenticationBloc authenticationBloc;
final AuthenticateCredentialsUsecase authenticateCredentialsUsecase;
//code
Stream<LoginState> mapEventToState(
LoginEvent event,
) async* {
//code
authenticationBloc.add(AuthenticationLogin());
yield LoginLoadSuccess();
//code
}
}
我要完成的工作:
class _AppViewState extends State<AppView> {
final _navigatorKey = GlobalKey<NavigatorState>();
NavigatorState get _navigator => _navigatorKey.currentState;
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: _navigatorKey,
builder: (context, child) {
return BlocListener<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
if (state is AuthenticationAuthenticated) {
_navigator.pushAndRemoveUntil<void>(
HomePage.route(),
(route) => false,
);
}
else if (state is AuthenticationUnauthenticated){
_navigator.pushAndRemoveUntil<void>(
LoginScreen.route(),
(route) => false,
);
}
},
child: child,
);
},
onGenerateRoute: (_) => SplashPage.route(),
);
}
}
如您所见,用户当前位于LoginScreen中,一旦登录成功,我需要在AuthenticationBloc()中产生AuthenticationAuthenticated()状态,以便将用户定向到HomePage()
由于我的登录逻辑发生在LoginBloc内部,因此如何在LoginBloc()内部产生AuthenticationBloc()的AuthenticationAuthenticated()状态。
答案 0 :(得分:0)
这是一种方法。您必须调用BlocBuilder来处理构建小部件以响应新状态。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
debugShowCheckedModeBanner: false,
home: BlocBuilder<AuthenticationBloc, AuthenticationState>(
builder: (context, state) {
//If the login is successful, show homepage
if (state is AuthenticationAuthenticated) {
return HomePage();
}
//If the login failed, show login screen
if (state is AuthenticationUnauthenticated) {
return LoginScreen();
}
//If the login is in process, show loading indicator
if (state is AuthenticationInProgress) {
return LoadingIndicator();
}
return SplashScreen();
},
),
);
}
}
首先,状态为AuthenticationUnauthenticated并显示登录屏幕。如果登录成功,则显示主页,否则,将显示LoginScreen。
class LoginBloc extends Bloc<LoginEvent, LoginState> {
final AuthenticationBloc authenticationBloc;
final AuthenticateCredentialsUsecase authenticateCredentialsUsecase;
//code
Stream<LoginState> mapEventToState(
LoginEvent event,
) async* {
if(event is LoginButtonPressed) {
// some logic code
// eg. : final response = UserRepository.login(username: event.username, password: event.password);
authenticationBloc.add(AuthenticationLogin());
//code
}
}
}
这是用于处理身份验证的AuthenticationBloc()代码。
class AuthenticationBloc extends Bloc<AuthenticationEvent, AuthenticationState>{
//code
Stream<AuthenticationState> mapEventToState(
AuthenticationEvent event,
) async* {
if(event is AuthenticationLogin) {
yield AuthenticationInProgress();
//code
yield AuthenticationAuthenticated();
}
}
}
答案 1 :(得分:0)
_controller.add(AuthenticationStatus.authenticated);
AuthenticationBloc
AuthenticationBloc({
@required CheckAuthenticationStatusUsecase checkAuthenticationStatus,
@required LogoutAuthenticatedUserUsecase logoutAuthenticatedUser,
@required AuthenticateCredentialsUsecase authenticateCredentials,
}) : assert(checkAuthenticationStatus != null),
assert(logoutAuthenticatedUser != null),
assert(authenticateCredentials != null),
checkAuthenticationStatusUsecase = checkAuthenticationStatus,
logoutAuthenticatedUserUsecase = logoutAuthenticatedUser,
authenticateCredentialsUsecase = authenticateCredentials,
super(AuthenticationInitial()) {
add(AuthenticationStatusRequested());
_loginStatusSubscription =
authenticateCredentialsUsecase.status.listen((event) {
if (event == AuthenticationStatus.authenticated) {
add(AuthenticationLogin());
}
});
}
AuthenticateCredentialsUsecase
final _controller = StreamController<AuthenticationStatus>();
Stream<AuthenticationStatus> get status async* {
yield AuthenticationStatus.unknown;
yield* _controller.stream;
}
void dispose() => _controller.close();
@override
Future<Either<Failure, AuthenticatedUser>> call(AuthenticationParams params) async {
final result = await repository.authenticateCredentials(params.userName, params.password);
if(result is Right){
_controller.add(AuthenticationStatus.authenticated);
}
return result;
}