How to use a provider inside of another provider in Flutter

前端 未结 4 972
遇见更好的自我
遇见更好的自我 2021-02-14 08:21

I want to create an app that has an authentication service with different permissions and functions (e.g. messages) depending on the user role.

So I create

相关标签:
4条回答
  • 2021-02-14 08:36

    Seems like this would be a lot easier with Riverpod, especially the idea of passing a parameter into a .family builder to use the provider class as a cookie cutter for many different versions.

    0 讨论(0)
  • 2021-02-14 08:40

    From version >=4.0.0, we need to do this a little differently from what @updatestage has answered.

    return MultiProvider(
      providers: [
        ChangeNotifierProvider(builder: (_) => Auth()),
        ChangeNotifierProxyProvider<Auth, Messages>(
          update: (context, auth, previousMessages) => Messages(auth),
          create: (BuildContext context) => Messages(null),
        ),
      ],
      child: MaterialApp(
        ...
      ),
    );
    
    0 讨论(0)
  • 2021-02-14 08:51

    Thanks for your answer. In the meanwhile, I solved it with another solution:

    In the main.dart file I now use ChangeNotifierProxyProvider instead of ChangeNotifierProvider for the depending provider:

    // main.dart
    return MultiProvider(
          providers: [
            ChangeNotifierProvider(builder: (_) => Auth()),
            ChangeNotifierProxyProvider<Auth, Messages>(
              builder: (context, auth, previousMessages) => Messages(auth),
              initialBuilder: (BuildContext context) => Messages(null),
            ),
          ],
          child: MaterialApp(
            ...
          ),
        );
    

    Now the Messages provider will be rebuilt when the login state changes and gets passed the Auth Provider:

    class Messages extends ChangeNotifier {
        final Auth _authProvider;
    
        List<Message> _messages = [];
        List<Message> get messages => _messages;
    
        Messages(this._authProvider) {
            if (this._authProvider != null) {
                if (_authProvider.loggedIn) fetchMessages();
            }
        }
    
        ...
    }
    
    0 讨论(0)
  • 2021-02-14 08:56

    It's simple: the first Provider provides an instance of a class, for example: LoginManager. The other Provides MessageFetcher. In MessageFetcher, whatever method you have, just add the Context parameter to it and call it by providing a fresh context.

    Perhaps your code could look something like this:

    MessageFetcher messageFetcher = Provider.of<ValueNotifier<MessageFetcher>>(context).value;
    String message = await messageFetcher.fetchMessage(context);
    

    And in MessageFetcher you can have:

    class MessageFetcher {
      Future<String> fetchMessage(BuildContext context) {
        LoginManager loginManager = Provider.of<ValueNotifier<LoginManager>>(context).value;
        loginManager.ensureLoggedIn();
        ///...
      }
    }
    
    0 讨论(0)
提交回复
热议问题