如何在没有BuildContext的情况下使用提供程序?

时间:2020-10-02 21:17:00

标签: flutter

我有一个具有login()和logout()方法的authProvider(扩展ChangeNotifier)。 我还有一个apiProvider(与Dio一起使用),并且对于每个请求所捕获的所有Eror,如果它是401,我都会将logout()方法触发到authProvider中。 但是我没有上下文,所以这似乎是不可能的。

我该怎么办?

主要(部分)

main() {
  GetIt.I.registerSingleton<ApiProvider>(ApiProvider());
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (_) => AuthProvider(),
        ),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return OverlaySupport(
      child: MaterialApp(
        title: 'Serialtrip',
        debugShowCheckedModeBanner: false,
        theme: defaultTheme,
        home: _showScreen(context),
      ),
    );
  }
}

Widget _showScreen(BuildContext context) {
  switch (context.watch<AuthProvider>().loggedInStatus) {
    case Status.Authenticating:
      return Splash();
    case Status.LoggedIn:
      return Home();
    default:
      return Login();
  }
}

APIPROVIDER

class ApiProvider {
  final dioClient.Dio _client = new dioClient.Dio();
  final storage = new FlutterSecureStorage();

  dioClient.Dio get client => _client;

  ApiProvider() {
    _client.options.baseUrl = BACKEND_URI;
    _client.options.connectTimeout = 2000; //2s
    _client.options.receiveTimeout = 2000; //2s
    _client.interceptors.add(dioClient.InterceptorsWrapper(onRequest: (dioClient.RequestOptions options) async {
      String token = await storage.read(key: 'token');
      options.headers = {
        HttpHeaders.authorizationHeader: 'Bearer $token',
      };
      return options;
    }, onError: (dioClient.DioError e) async {
      if (dioClient.DioErrorType.RESPONSE == e.type && 401 == e.response.statusCode) {
        print('401 -> deconnexion !');
        // Provider.of<AuthProvider>(context).logout();
      } else {
        showSimpleNotification(
          Text('${e.type} - ${e.error}'),
          position: NotificationPosition.bottom,
        );
      }
      return e;
    }));
  }
}

1 个答案:

答案 0 :(得分:0)

我有一个解决方案,但我不知道这是否是个好方法。

在main.dart中进入我使用的版本

GetIt.instance<ApiProvider>().initContext(context);

因此,在apiProvider中,我现在有了BuildContext,我可以像这样将方法调用到je AuthProvider中:

_context.read<AuthProvider>().logout();

但是上下文的注入同时触发。但是我没有其他解决方案,它可以正常工作!