我想创建一个具有authentication service
且具有不同权限和功能(例如消息)的应用程序,具体取决于用户角色。
因此,我为用户和登录管理创建了一个Provider
,为用户看到的消息创建了另一个。
现在,我想在用户登录时一次获取消息。在Widgets
中,我可以通过Provider.of<T>(context)
访问提供者,我想这是一种Singleton
。但是如何从另一个类(在本例中为另一个Provider)访问它?
答案 0 :(得分:5)
在版本> = 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(
...
),
);
答案 1 :(得分:2)
感谢您的回答。同时,我用另一种解决方案解决了它:在main.dart文件中,我现在使用ChangeNotifierProxyProvider
而不是ChangeNotifierProvider
作为Dependig提供程序:
// main.dart
return MultiProvider(
providers: [
ChangeNotifierProvider(builder: (_) => Auth()),
ChangeNotifierProxyProvider<Auth, Messages>(
builder: (context, auth, previousMessages) => Messages(auth),
initialBuilder: (BuildContext context) => Messages(null),
),
],
child: MaterialApp(
...
),
);
现在,登录状态更改并通过Auth Provider时,将重建Messages提供程序:
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();
}
}
...
}
答案 2 :(得分:2)
在 ChangeNotifierProxyProvider 的构造函数中传递另一个提供程序可能会导致您丢失状态,在这种情况下,您应该尝试以下操作。
if (HWND hwnd = GetShellWindow())
{
ULONG dwProcessId;
if (GetWindowThreadProcessId(hwnd, &dwProcessId))
{
HANDLE hToken;
if (HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcessId))
{
BOOL b = OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_IMPERSONATE, &hToken);
CloseHandle(hProcess);
if (b)
{
if (0 <= SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, hToken, &pszPath))
{
DbgPrint("<%S>\n", pszPath);
CoTaskMemFree(pszPath);
}
CloseHandle(hToken);
}
}
}
}
ChangeNotifierProxyProvider<MyModel, MyChangeNotifier>(
create: (_) => MyChangeNotifier(),
update: (_, myModel, myNotifier) => myNotifier
..update(myModel),
);
答案 3 :(得分:0)
很简单:第一个提供程序提供一个类的实例,例如:LoginManager
。另一个提供MessageFetcher
。在MessageFetcher
中,无论使用哪种方法,只需向其添加Context
参数,然后通过提供新的上下文进行调用。
也许您的代码可能看起来像这样:
MessageFetcher messageFetcher = Provider.of<ValueNotifier<MessageFetcher>>(context).value;
String message = await messageFetcher.fetchMessage(context);
在MessageFetcher
中,您可以拥有:
class MessageFetcher {
Future<String> fetchMessage(BuildContext context) {
LoginManager loginManager = Provider.of<ValueNotifier<LoginManager>>(context).value;
loginManager.ensureLoggedIn();
///...
}
}
答案 4 :(得分:0)
使用Riverpod看起来像这样会容易得多,特别是将参数传递到const WrapperForm = (props) => {
const {record} = props;
return (
<SimpleForm {...props}>
<TextInput source="id" label="ID Input"/>
</SimpleForm>
);
}
构建器中以将提供者类用作许多不同版本的cookie切割器的想法。