Если состояние в BLoC (Business Logic Component) не обновляется, то причин может быть несколько. Вот некоторые из них:
1. В методе, который должен обновлять состояние, не вызывается `emit()`.
2. Может быть ошибка в логике или условиях, при которых должно произойти обновление состояния.
3. Потоки данных могут быть неправильно настроены, и слушатели не получают изменения состояния.
4. Виджет, использующий BLoC, может быть неправильно построен и не реагирует на изменения состояния из-за неправильного использования `BlocBuilder`, `BlocListener` или `BlocConsumer`.
5. Возможно, забыли добавить `BlocProvider` в верхнюю часть дерева виджетов или неправильно используют контекст для доступа к BLoC.
6. Если используете `equatable`, убедитесь, что определены все свойства, которые должны вызывать обновление, в списке props.
Чтобы организовать авторизацию в приложении с использованием двух BLoC'ов, можно использовать следующую стратегию:
### AuthBloc:
Этот BLoC будет отвечать за глобальное состояние авторизации пользователя. Он будет содержать состояния, такие как Unauthenticated, Authenticated и Loading.
Пример AuthBloc:
```dart
enum AuthStatus {
unauthenticated,
authenticated,
loading,
}
class AuthBloc extends Bloc<AuthEvent, AuthState> {
final UserRepository userRepository;
AuthBloc({required this.userRepository}) : super(Unauthenticated()) {
on<AppStarted>(_onAppStarted);
on<LoggedIn>(_onLoggedIn);
on<LoggedOut>(_onLoggedOut);
}
void _onAppStarted(AppStarted event, Emitter<AuthState> emit) {
final bool hasToken = await userRepository.hasToken();
if (hasToken) {
emit(Authenticated());
} else {
emit(Unauthenticated());
}
}
void _onLoggedIn(LoggedIn event, Emitter<AuthState> emit) {
emit(Authenticated());
}
void _onLoggedOut(LoggedOut event, Emitter<AuthState> emit) {
await userRepository.deleteToken();
emit(Unauthenticated());
}
}
```
### LoginBloc:
Этот BLoC будет отвечать за процесс входа в аккаунт, включая валидацию формы авторизации и передачу данных для авторизации в `UserRepository`.
Пример LoginBloc:
```dart
class LoginBloc extends Bloc<LoginEvent, LoginState> {
final AuthBloc authBloc;
final UserRepository userRepository;
LoginBloc({
required this.authBloc,
required this.userRepository,
}) : super(LoginInitial()) {
on<LoginButtonPressed>(_onLoginButtonPressed);
}
void _onLoginButtonPressed(LoginButtonPressed event, Emitter<LoginState> emit) async {
emit(LoginLoading());
try {
final token = await userRepository.authenticate(
username: event.username,
password: event.password,
);
authBloc.add(LoggedIn(token: token));
emit(LoginInitial());
} catch (error) {
emit(LoginFailure(error: error.toString()));
}
}
}
```
### Реализация пользовательского интерфейса:
1. Используйте `BlocProvider` для предоставления `AuthBloc` в вашем приложении.
2. В виджете уровня приложения используйте `BlocListener` для прослушивания изменений состояния в `AuthBloc`.
3. Используйте `BlocProvider` для предоставления `LoginBloc` на экране входа.
4. Используйте `BlocBuilder` для управления состоянием кнопки входа и отображения сообщений об ошибке на экране входа.
Это обеспечит чистое разделение ответственности и легко масштабируемую ар