[英]Flutter Riverpod: how to pass multiple arguments in family?
I can pass one argument along with ProviderScope in Riverpod ChangeNotifierProvider family.我可以在 Riverpod ChangeNotifierProvider 系列中将一个参数与 ProviderScope 一起传递。 But I need to pass more than one/multiple arguments/dependencies.但我需要传递不止一个/多个参数/依赖项。 For example I have to pass context to access other providers value via context.read(provider) and dependencies from UI widget, may be some more also.例如,我必须传递上下文以通过 context.read(provider) 和来自 UI 小部件的依赖项访问其他提供者的值,可能还有更多。
Example here:这里的例子:
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();
}
}
If you want to pass multiple values into the Provider
when you create it, you can use the family
modifier with a custom type.如果您想在创建Provider
时将多个值传递给它,您可以使用带有自定义类型的family
修饰符。
For example, in this instance, you may want to replace the String
value with a Person
value:例如,在本例中,您可能希望将String
值替换为Person
值:
final multipleGreetingProvider = Provider.family<String, Person>(
(_, person) {
return "Hello, ${person.name} ${person.surname}!";
},
);
You can now pass a Person
value into the Provider
when you create it:您现在可以在创建时将Person
值传递给Provider
:
// prints "Hello, Paul Halliday!"
sayHello(WidgetRef ref) {
ref.read(
multipleGreetingProvider(
Person('Paul', 'Halliday'),
)
);
}
This can be extended infinitely.这可以无限扩展。 If you now have multiple classes you'd like to pass in, you can combine this into a logical unit.如果您现在有多个要传入的类,则可以将其组合成一个逻辑单元。
For example, this may look like:例如,这可能如下所示:
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,
),
));
}
This shows how to get around the problem of having to pass in multiple values into the Provider
using family
.这显示了如何解决必须使用family
将多个值传递到Provider
。
This is another way of providing multiple arguments. Use List<dynamic>>
这是提供多个 arguments 的另一种方式。使用List<dynamic>>
final restaurantProvider = FutureProvider.autoDispose
.family<RecordModel, List<dynamic>>(
(ref, args) => ref.read(rsProvider).load(args[0], args[1]));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.