我可以在Riverpod ChangeNotificationerProvider家族中传递一个参数和ProviderScope。但我需要传递不止一个/多个参数/依赖项。例如,我必须通过context.read(provider)和UI小部件的依赖关系来传递上下文以访问其他提供者的值,可能还有更多。
此处示例:
final restaurantProvider = ChangeNotifierProvider.family(
(ref, BuildContext context, Restaurant? restaurant) => RestaurantNotifier(
context: context,
restaurant: restaurant,
),
);
class RestaurantNotifier extends ChangeNotifier {
RestaurantNotifier(
{required BuildContext context, required Restaurant? restaurant}) {
getPlaceMark(restaurant);
checkIsSaved(context, restaurant!.id);
}
getPlaceMark(Restaurant? restaurant) async {
if (restaurant!.latitude != null && restaurant.longitude != null) {
List<Placemark> placemarkData = await LocationHelper.getPlaceMark(
lat: double.tryParse(restaurant.latitude!)!,
long: double.tryParse(restaurant.longitude!)!,
);
placemark = placemarkData[0];
}
}
checkIsSaved(BuildContext context, int? id) {
final savedRestaurantsId = context.read(savedRestaurantsIdProvider.state);
isSaved = savedRestaurantsId.contains(id);
notifyListeners();
}
}
如果您想在创建Provider
时将多个值传递给它,可以将family
修饰符与自定义类型一起使用。
例如,在本例中,您可能希望将String
值替换为Person
值:
final multipleGreetingProvider = Provider.family<String, Person>(
(_, person) {
return "Hello, ${person.name} ${person.surname}!";
},
);
现在,您可以在创建Provider
时将Person
值传递给它:
// prints "Hello, Paul Halliday!"
sayHello(WidgetRef ref) {
ref.read(
multipleGreetingProvider(
Person('Paul', 'Halliday'),
)
);
}
这可以无限扩展。如果您现在有多个想要传递的类,您可以将它们组合成一个逻辑单元。
例如,这可能看起来像:
class Household {
final List<Person> members;
final int rooms;
Household(this.members, this.rooms);
}
final householdProvider = Provider.family<String, Household>(
(_, household) {
return "Household has ${household.rooms} rooms and ${household.members.length} members.";
},
);
// prints "Household has 3 rooms and 1 members."
householdData(WidgetRef ref) {
ref.read(householdProvider(
Household(
[
Person('Paul', 'Halliday'),
],
3,
),
));
}
这展示了如何绕过必须使用family
将多个值传递到Provider
的问题。
参考。
这是提供多个参数的另一种方式。使用List<dynamic>>
final restaurantProvider = FutureProvider.autoDispose
.family<RecordModel, List<dynamic>>(
(ref, args) => ref.read(rsProvider).load(args[0], args[1]));
您可以在Dart 3中使用typedef。它提供了简单易用的族参数。
typedef Parameters= ({String type, int maxPrice});
然后你可以使用像这样的提供商
final providerName= FutureProvider.family<Activity, Parameters>((ref, arguments) async {
.......
});
现在很简单