我想使用provider
(ChangeNotifierProvider
)和ChangeNotifier
来管理应用程序状态。但是如何从另一个模型中的一个模型访问状态?
用例:在聊天应用程序中,一种用于存储用户信息的模型。其他模型使用用户信息(例如,用户ID)来调用数据库(Firestore)并获取聊天数据流。
例如:
class Model1 extends ChangeNotifier {
final List<Item> items = [];
class Model2 extends ChangeNotifier {
//Access items from Model1 here
items;
这可能吗?我不喜欢拥有大型模型,因为很难维护。
谢谢!
答案 0 :(得分:2)
从v4到ChangeNotifierProxyProvider
的提供者可以这样构造:
ChangeNotifierProxyProvider<Foo, Bar>(
create: (_) => Bar(),
update: (_, foo, bar) => bar
..count = foo.count,
)
请注意,initialBuilder:
已更改为create:
,并且
builder:
至update:
答案 1 :(得分:1)
这里我举了一个简单的例子
main.dart
ChangeNotifierProxyProvider<AuthProvider, ProductsProvider>(
create: (context) => ProductsProvider(),
update: (context, auth, previousProducts) => previousProducts
..update(auth.token, previousProducts.items == null ? [] : previousProducts.items),
),
authProvider.dart
class AuthProvider with ChangeNotifier {
String _token;
// _token is a response token.
String get token {
return _token;
}
productsProvider.dart
Product是一类单品
class ProductsProvider with ChangeNotifier {
List<Product> _items = [];
String _authToken;
void update(authToken, items) {
_items = items;
_authToken = authToken;
notifyListeners();
}
}
产品.dart
class Product with ChangeNotifier {
final String id;
final String title;
final String description;
final double price;
final String imageUrl;
bool isFavorite;
Product({
@required this.id,
@required this.title,
@required this.description,
@required this.price,
@required this.imageUrl,
this.isFavorite = false,
});
}
答案 2 :(得分:0)
使用provider
,一个模型无法访问另一模型。
相反,您应该使用ProxyProvider
来组合其他模型。
您的模型如下:
class Foo with ChangeNotifier {
int count = 0;
void increment() {
count++;
notifyListeners();
}
}
class Bar with ChangeNotifier {
int _count;
int get count => _count;
set count(int value) {
if (value != count) {
_count = value;
notifyListeners();
}
}
}
然后您可以通过这种方式使用ChangeNotifierProxyProvider
(假设您的小部件树中有更高的`ChangeNotifierProvider):
ChangeNotifierProxyProvider<Foo, Bar>(
initialBuilder: (_) => Bar(),
builder: (_, foo, bar) => bar
..count = foo.count, // Don't pass `Foo` directly but `foo.count` instead
)
答案 3 :(得分:0)
我正在尝试实现相同的场景,这是我的代码: 主文件:
ChangeNotifierProvider<SharedPreferencesData>(
create: (context) => SharedPreferencesData(),
),
ChangeNotifierProxyProvider<SharedPreferencesData, DatabaseService>(
create: (_) => DatabaseService(),
update: (_, sharedPreferencesData, databaseService) {
print('ChangeNotifierProxyProvider RAN');
databaseService..setSpCompanyId = sharedPreferencesData.sPCompanyId;
return null;
},
),
SharedPreferences数据文件:
class SharedPreferencesData with ChangeNotifier {
String sPCompanyId = '';
void setCompanyId(String cpID) {
sPCompanyId = cpID;
print('setCompanyId sPCompanyId:$sPCompanyId');
notifyListeners();
}
}
DataBaseService文件:
class DatabaseService with ChangeNotifier {
String sPCompanyId = 'empty';
String get getSpCompanyId => sPCompanyId;
set setSpCompanyId(String value) {
print('value in setter database before if: $value');
if (value != getSpCompanyId) {
print('value in setter database: $value');
sPCompanyId = value;
notifyListeners();
}
}
DatabaseService类不会更新。我添加了打印件以找出正在运行的内容和未运行的内容。 运行代码时,Shared_Preferences / setCompanyId方法中的打印正确运行。 main.dart文件中的打印功能print('ChangeNotifierProxyProvider RAN');在DataBaseService文件中打印AND('在setter数据库中的值:$ value');无法运行。
我想念什么?为什么SharedPreferencesData中的notify sPCompanyId setter notifyListeners()不通过ChangeNotifierProxyProvider更新DatabaseService字符串sPCompanyId?谢谢!