[英]Flutter Provider. How to have multiple instances of the same provider type?
So I'm a little confused about how to port an application using setstate to provider.所以我对如何使用 setstate 将应用程序移植到提供者有点困惑。
Let's say I have a person model which extends provider.假设我有一个扩展提供者的人 model。 Now I also want to have multiple person reports.现在我也想要多人报告。 Each report has it's own properties such, title, created date etc plus a list of people.每个报告都有自己的属性,例如标题、创建日期等以及人员列表。
The trouble I'm having understanding is how would I create a provider per person and per person report?我遇到的麻烦是如何为每人和每人报告创建提供者? All the examples I've seen of using provider appear to have just one instance of the provider.我见过的所有使用提供程序的示例似乎都只有一个提供程序实例。
Effectively I would want to be able to edit person 'A's values without it effecting person 'B's实际上,我希望能够在不影响人 B 的情况下编辑人 A 的值
EDIT:编辑:
Each instance of my object will need a separate state.我的 object 的每个实例都需要一个单独的 state。 How can provider manage states of multiple objects all of the same type?.提供者如何管理所有相同类型的多个对象的状态?
EDIT 2:编辑2:
I'll try to clarify further with a different example.我将尝试用一个不同的例子进一步澄清。 Imagine the counter widget that is the default example when creating a flutter app.想象一下创建 flutter 应用程序时默认示例的计数器小部件。 What if I require a list of dynamically created counters (maybe 10, maybe 100 of them).如果我需要一个动态创建的计数器列表(可能是 10 个,也可能是 100 个)。 Would each counter would have it's own provider controlling it's state and if so, how would we create that?每个计数器都会有它自己的提供程序来控制它的 state,如果是这样,我们将如何创建它?
There is no hard rule on how to structure your data.关于如何构建数据没有硬性规定。 From what i understand from you question:根据我对您的问题的理解:
class Person{
String name;
Report reportData;
Person(this.name, this.reportData);
}
class Report{
String title;
Map<String, dynamic> data;
Report(this.title, this.data);
}
class PersonsData with ChangeNotifier
{
List<Person> l1 = [];
void addData()
{
l1.add(Person('John', Report('report1', {'dataTitle' : 'datDescription'})));
}
}
Now with PersonsData class you can manage your persons.现在使用 PersonsData class,您可以管理您的人员。 Every person has a report type object which represents the data within.每个人都有一个报告类型 object 代表其中的数据。
I'm not sure if I'm understanding your question correctly, but a provider does not contain data, it just makes it available, and if you're talking about the provider package it helps other parts of your app get notified when changes have been done to your data.我不确定我是否正确理解了您的问题,但是提供程序不包含数据,它只是使其可用,如果您在谈论提供程序 package 它可以帮助您的应用程序的其他部分在更改时收到通知对您的数据进行了处理。 while a model is what you can make instances of.而 model 是您可以制作的实例。
Your state objects must be uniquely named types, otherwise, Provider can't distinguish them.您的 state 对象必须是唯一命名的类型,否则 Provider 无法区分它们。
You could create a base Person
class and then extend that base class into PersonA
, PersonB
, etc.您可以创建一个基础Person
class ,然后将该基础 class 扩展到PersonA
、 PersonB
等。
Then they can be controlled separately, but still rely on the base class' functionality.然后它们可以单独控制,但仍然依赖于基类的功能。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Person with ChangeNotifier {
String name;
Person(this.name);
void changeName(String newName) {
name = newName;
notifyListeners();
}
}
class PersonA extends Person {
PersonA(String value) : super(value);
}
class PersonB extends Person {
PersonB(String value) : super(value);
}
class ProviderDuplicatePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => PersonA('Billy Boy')),
ChangeNotifierProvider(create: (_) => PersonB('Francis')),
],
child: Scaffold(
appBar: AppBar(
title: Text('Provider Duplicate Types'),
),
body: DuplicateProviderStateObjects(),
)
);
}
}
class DuplicateProviderStateObjects extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: [
Text('Provider One:'),
Text(Provider.of<PersonA>(context).name),
ElevatedButton(
child: Text('Change Person A'),
onPressed: () => Provider.of<PersonA>(context, listen: false).changeName("Kong"),
)
],
),
Column(
children: [
Text('Provider Two:'),
Text(context.watch<PersonB>().name),
ElevatedButton(
child: Text('Change Person B'),
onPressed: () => Provider.of<PersonB>(context, listen: false).changeName("Godzilla"),
)
],
),
],
),
);
}
}
I don't know if there is a way to create Providers dynamically, like in the example of edit2, but if you want to create multiple providers of the same type without repeating code you could pass a type T to the class which extends ChangeNotifier.我不知道是否有一种方法可以动态创建提供程序,就像在 edit2 的示例中一样,但是如果您想创建多个相同类型的提供程序而不重复代码,您可以将类型 T 传递给扩展 ChangeNotifier 的 class。
class Counter<T> extends ChangeNotifier {
late int value;
Counter() { value = 0; }
int get getValue => value;
void increase() {
value += 1;
notifyListeners();
}
}
Passing different types should create different classes in memory that will manage the state of these different counters.传递不同的类型应该在 memory 中创建不同的类,这些类将管理这些不同计数器的 state。 Illustration:插图:
class A {}
class B {}
class C {}
MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => Counter<A>()),
ChangeNotifierProvider(
create: (_) => Counter<B>()),
ChangeNotifierProvider(
create: (_) => Counter<C>()),
],
child: Home(),
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.