如何在 Flutter 中的另一个提供者中使用一个提供者

upd*_*age 18 dart flutter flutter-layout

我想创建一个authentication service具有不同权限和功能(例如消息)的应用程序,具体取决于用户角色。

所以我Provider为用户和登录管理创建了一个,为用户可以看到的消息创建了另一个。

现在,我想在用户登录时获取消息(一次)。在 中Widgets,我可以通过访问提供程序Provider.of<T>(context),我想这是一种Singleton. 但是我如何从另一个类(在这种情况下是另一个提供者)访问它?

upd*_*age 23

感谢您的回答。同时,我用另一个解决方案解决了这个问题:

main.dart我现在使用的文件中,ChangeNotifierProxyProvider而不是ChangeNotifierProvider用于依赖的提供程序:

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

现在,当登录状态更改并通过身份验证提供程序时,将重建消息提供程序:

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();
        }
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

  • 除此之外,这里有一篇文章解释了所有“Provider” - https://medium.com/flutter-community/making-sense-all-of-those-flutter-providers-e842e18f45dd (6认同)

小智 15

在 ChangeNotifierProxyProvider 的构造函数中传递另一个提供程序可能会导致您丢失状态,在这种情况下您应该尝试以下操作。

ChangeNotifierProxyProvider<MyModel, MyChangeNotifier>(
  create: (_) => MyChangeNotifier(),
  update: (_, myModel, myNotifier) => myNotifier
    ..update(myModel),
);
Run Code Online (Sandbox Code Playgroud)
class MyChangeNotifier with ChangeNotifier {
  MyModel _myModel;

  void update(MyModel myModel) {
    _myModel = myModel;
  }
}
Run Code Online (Sandbox Code Playgroud)


Ana*_*hag 14

版本 >=4.0.0 开始,我们需要与@updatestage 的回答略有不同。

return MultiProvider(
  providers: [
    ChangeNotifierProvider(builder: (_) => Auth()),
    ChangeNotifierProxyProvider<Auth, Messages>(
      update: (context, auth, previousMessages) => Messages(auth),
      create: (BuildContext context) => Messages(null),
    ),
  ],
  child: MaterialApp(
    ...
  ),
);
Run Code Online (Sandbox Code Playgroud)