![](/img/trans.png)
[英]How to call a riverpod provider outside of widget tree/widget class?
[英]How to initialize widget's provider with riverpod 2?
我的問題是關於 Riverpod 的。
我有一個帶有 2 個選項卡的小部件。 當我更改選項卡時,如果我選擇第一個選項卡,我想用“地址”值更新屬性(infoShare),如果我選擇第二個選項卡,我想用“publicKey”值更新屬性(infoShare)。
我用通知程序來做到這一點。 沒問題。 但是當我第一次實例化主要小部件時,我的提供者沒有初始化。 所以我需要修復它以創建一個特定的提供程序來初始化它並使用 ProviderScope。
這是初始化我的小部件的好方法嗎?
這是我的代碼。 它有效,但我不知道它是否是好的解決方案。 也許 Riverpod 的注釋會有所幫助
final _contactDetailInfoShareProviderArgs = Provider<Contact>(
(ref) {
throw UnimplementedError();
},
);
final _contactDetailInfoShareProvider = NotifierProvider.autoDispose
.family<ContactDetailInfoShareNotifier, String, Contact>(
() {
return ContactDetailInfoShareNotifier();
},
);
class ContactDetailInfoShareNotifier
extends AutoDisposeFamilyNotifier<String, Contact> {
ContactDetailInfoShareNotifier();
@override
String build(Contact arg) {
return arg.address.toUpperCase();
}
void setInfoShare(int tab, Contact contact) {
if (tab == 1) {
state = contact.publicKey.toUpperCase();
} else {
state = contact.address.toUpperCase();
}
}
}
abstract class ContactDetailProvider {
static final contactDetailInfoShare = _contactDetailInfoShareProvider;
static final contactDetailInfoShareProviderArgs =
_contactDetailInfoShareProviderArgs;
}
class ContactDetail extends ConsumerWidget {
const ContactDetail({
required this.contact,
super.key,
});
final Contact contact;
@override
Widget build(BuildContext context, WidgetRef ref) {
return ProviderScope(
overrides: [
ContactDetailProvider.contactDetailInfoShareProviderArgs
.overrideWithValue(
contact,
),
],
child: ContactDetailBody(
contact: contact,
),
);
}
}
class ContactDetailBody extends ConsumerWidget {
const ContactDetailBody({
required this.contact,
super.key,
});
final Contact contact;
@override
Widget build(BuildContext context, WidgetRef ref) {
return Column(
children: <Widget>[
Expanded(
child: Container(
child: ContainedTabBarView(
tabs: [
Text('tab1'),
Text('tab2'),
],
views: [
ContactDetailTab1(),
ContactDetailTab2(),
],
onChange: (p0) {
ref
.watch(
ContactDetailProvider.contactDetailInfoShare(contact)
.notifier,
)
.setInfoShare(p0, contact);
},
),
),
),
AppButton(
'Share',
onPressed: () {
print(
ref.watch(
ContactDetailProvider.contactDetailInfoShare(
ref.read(
ContactDetailProvider.contactDetailInfoShareProviderArgs,
),
),
),
);
},
)
],
);
}
}
ProviderScope
不應用於您的應用程序的根以外,或僅用於測試。 它不是為在您的小部件中使用而設計的。 還有許多其他選項可以初始化您的提供者,考慮使用.family
或使用一些具有三種狀態的StateNotifierProvider
loading
, error
, value
,您可以loading
初始值,初始化后您可以獲得value
state 。或者考慮使用新的Riverpod
代碼生成有一些更復雜的邏輯來初始化你的提供者。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.