如何将flutter_blocking与go_router一起使用

s5a0g9ez  于 2022-11-25  发布在  Flutter
关注(0)|答案(4)|浏览(123)

bounty将在5天后过期。回答此问题可获得+50的声望奖励。Sunshine正在寻找此问题的最新答案

我已经构建了一个应用程序,其中我使用flutter_bloc。我想使用go_router进行导航。但对于动态路由,我如何使用GoRouter refreshListener参数和flutter_bloc

GoRouter(
  routes: [
    GoRoute(
      path: '/',
      name: 'home',
      pageBuilder: (context, state) => HomePage.page(),
    ),
    GoRoute(
      path: '/login',
      name: 'login',
      pageBuilder: (context, state) => LoginPage.page(),
    ),
  ],
  redirect: (state) {
    final isLoggedIn =
        bloc.state.status == AuthenticationStatus.authenticated;
    final isLoggingIn = state.location == '/login';

    if (!isLoggingIn && !isLoggingIn) return '/login';
    if (isLoggedIn && isLoggingIn) return "/";

    return null;
  },
  refreshListenable: 
   );
guz6ccqo

guz6ccqo1#

因为bloc也以流的形式返回状态,所以你可以直接使用它。

refreshListenable = GoRouterRefreshStream(authenticationBloc.stream),
zhte4eai

zhte4eai2#

对我来说,将changeNotifier与Bloc类混合并从事件中调用notififyListener()是有效的
这是我的集体课

class AuthenticationBloc extends Bloc<AuthenticationEvent, AuthenticationState>
    with ChangeNotifier {
  AuthenticationBloc(
      {required AuthenticationRepository authenticationRepository})
      : _authenticationRepository = authenticationRepository,
        super(const AuthenticationState.unknown()) {
    on<AppStarted>(_onAppStarted);

    on<AuthenticationUserChanged>(_onAuthenticationUserChanged);

    on<AuthenticationLogoutRequested>(_onAuthenticationLogoutRequested);

    _userSubscription = _authenticationRepository.user
        .listen((user) => add(AuthenticationUserChanged(user)));
  }

  final AuthenticationRepository _authenticationRepository;

  late StreamSubscription<User> _userSubscription;

  @override
  Future<void> close() {
    _userSubscription.cancel();
    return super.close();
  }

  FutureOr<void> _onAppStarted(
      AppStarted event, Emitter<AuthenticationState> emit) {
    emit(AuthenticationState.unknown());
  }

  FutureOr<void> _onAuthenticationUserChanged(
      AuthenticationUserChanged event, Emitter<AuthenticationState> emit) {
    final status = event.user != User.empty
        ? AuthenticationState.authenticated(event.user)
        : const AuthenticationState.unauthenticated();
    emit(status);
    notifyListeners();
  }

  FutureOr<void> _onAuthenticationLogoutRequested(
      AuthenticationLogoutRequested event, Emitter<AuthenticationState> emit) {
    unawaited(_authenticationRepository.logOut());
  }
}

这是GoRouter

GoRouter routes(AuthenticationBloc bloc) {
  return GoRouter(
      routes: [
        GoRoute(
          path: '/',
          name: 'home',
          builder: (context, state) => const HomePage(),
        ),
        GoRoute(
          path: '/login',
          name: 'login',
          builder: (context, state) => const LoginPage(),
        ),
      ],
      redirect: (state) {
        final isLoggedIn =
            bloc.state.status == AuthenticationStatus.authenticated;
        final isLoggingIn = state.location == '/login';
        print(isLoggedIn);

        if (!isLoggedIn && !isLoggingIn) return '/login';
        if (isLoggedIn && isLoggingIn) return '/';

        return null;
      },
      refreshListenable: bloc);
}
yuvru6vn

yuvru6vn3#

也许你可以这样做:

class AuthStateNotifier extends ChangeNotifier {
  late final StreamSubscription<AuthState> _blocStream;
  AuthStateProvider(AuthBloc bloc) {
    _blocStream = bloc.stream.listen((event) {
      notifyListeners();
    });
  }

  @override
  void dispose() {
    _blocStream.cancel();
    super.dispose();
  }
}

代码来自this answer,希望你能理解。

mklgxw1f

mklgxw1f4#

检查一下这个example,go_router支持,因为最近的一个版本用一个Stream刷新,这将避免在你的代码中额外的 Package 。

相关问题