Firebase 如何将数据从一个提供者模型传递到另一个提供者模型?

Firebase 如何将数据从一个提供者模型传递到另一个提供者模型?,firebase,flutter,dart,google-cloud-firestore,flutter-packages,Firebase,Flutter,Dart,Google Cloud Firestore,Flutter Packages,我想使用提供程序(变更通知提供程序)和变更通知程序来管理应用程序状态。但如何从一个模型访问另一个模型中的状态 用例:在聊天应用程序中,一个模型用于存储用户信息。其他模型使用用户信息(例如用户id)调用数据库(Firestore)并获取聊天数据流 例如: class Model1 extends ChangeNotifier { final List<Item> items = []; class Model2 extends ChangeNotifier { //Access

我想使用
提供程序
变更通知提供程序
)和
变更通知程序
来管理应用程序状态。但如何从一个模型访问另一个模型中的状态

用例:在聊天应用程序中,一个模型用于存储用户信息。其他模型使用用户信息(例如用户id)调用数据库(Firestore)并获取聊天数据流

例如:

class Model1 extends ChangeNotifier {
  final List<Item> items = [];

class Model2 extends ChangeNotifier {
//Access items from Model1 here
items;
class Model1扩展了ChangeNotifier{
最终清单项目=[];
类Model2扩展了ChangeNotifier{
//在此处访问Model1中的项目
项目;
这可能吗?我不喜欢有很大的型号,因为很难维护




谢谢!

使用
提供商
,一个型号无法访问另一个型号

相反,您应该使用
ProxyProvider
,来组合其他模型

您的模型看起来像:

class Foo和ChangeNotifier{
整数计数=0;
无效增量(){
计数++;
notifyListeners();
}
}
带有ChangeNotifier的类栏{
整数计数;
int get count=>\u count;
设置计数(整数值){
如果(值!=计数){
_计数=数值;
notifyListeners();
}
}
}
然后,您可以通过这种方式使用
ChangeNotifierProxyProvider
(假设在小部件树的更高位置有一个`ChangeNotifierProvider):

ChangeNotifierProxyProvider(
initialBuilder:()=>Bar(),
建筑商:(uo,foo,bar)=>bar
…count=foo.count,//不要直接传递'foo',而是传递'foo.count'
)
ChangeNotifierProxyProvider
可以这样构造提供程序:

ChangeNotifierProxyProvider(
创建:()=>Bar(),
更新:(uo,foo,bar)=>bar
…count=foo.count,
)
请注意,
initialBuilder:
已更改为
create:

builder:
更新:

我正在尝试实现相同的场景,以下是我的代码: 主文件:

        ChangeNotifierProvider<SharedPreferencesData>(
      create: (context) => SharedPreferencesData(),
    ),
    ChangeNotifierProxyProvider<SharedPreferencesData, DatabaseService>(
      create: (_) => DatabaseService(),
      update: (_, sharedPreferencesData, databaseService) {
        print('ChangeNotifierProxyProvider RAN');
        databaseService..setSpCompanyId = sharedPreferencesData.sPCompanyId;
        return null;
      },
    ),
数据库服务文件:

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类没有更新。我添加了打印以确定哪些正在运行,哪些没有。 当我运行代码时,prints in Shared_Preferences/setCompanyId方法会正确运行。 但是main.dart文件print('ChangeNotifierProxyProvider run')和DataBaseService文件print('setter数据库中的值:$value')中的print函数没有运行

我遗漏了什么?为什么SharedReferencesData中的notify sPCompanyId setter notifyListeners()没有通过ChangeNotifierProxyProvider更新数据库服务字符串sPCompanyId?谢谢!

我已经尝试简单地实现了这一点。 提供程序版本^4.3.3 这里我给出了一个简单的例子

主飞镖

ChangeNotifierProxyProvider<AuthProvider, ProductsProvider>(
       create: (context) => ProductsProvider(),
       update: (context, auth, previousProducts) => previousProducts
            ..update(auth.token, previousProducts.items == null ? [] : previousProducts.items),
),

产品供应商

class AuthProvider with ChangeNotifier {
  String _token;
  // _token is a response token.
  String get token {
    return _token;
}
产品是单一产品的一类

class ProductsProvider with ChangeNotifier {
  List<Product> _items = [];
  String _authToken;
  void update(authToken, items) {
    _items = items;
    _authToken = authToken;
    notifyListeners();
  }
}

感谢您的回复!我正在尝试了解makeAPI调用是如何工作的。您是说我们无法从模型中访问另一个模型,所以我们使用
ChangeNotifierProxyProvider
将状态从
Model1
传递到
Model2
?您好,雷米,我有一个问题。如果在您的示例中
Bar
需要调用在
Foo
中定义的一些业务逻辑函数可以
Bar
获得
Foo
ChangeNotifier
实例,还是应该总是避免?在我的用例中,我有一个屏幕,其中有一个带有“父ChangeNotifier”的选项卡,每个选项卡都有不同的ChangeNotifier。有时选项卡需要触发“父”中的更改.还有其他更好的选择吗?谢谢你的出色工作!@Rémi Rousselet在打电话之前,你为什么要写“.”count@Rémi Rousselet,我有三个提供者,在其中一个提供者中,我想访问另外两个。我尝试了:ChangeNotifierProxyProvider(create:(BuildContext context)=>Einkauf(null),更新:(上下文,provider1,provider2,myNotifier)=>myNotifier..update(provider1,provider2))…但它只允许有一个参数。除了这个挑战,你的包太棒了!根据我的经验,使用
ChangeNotifierProxyProvider
会成为一场噩梦,因为随着时间的推移,事情变得越来越复杂。我不使用这种方法。相反,我按照干净的体系结构使用服务。服务对业务逻辑和功能一无所知它们通过服务定位器在应用程序间共享,例如
get_it
包。嗨,我有一个愚蠢的问题,为什么你要
bar..count=foo.count
而不是
bar(foo.count)
?如果你做了..对吗?@user1354934,你就可以重用旧的实例,这不是特别为新来者而做的蠢事!如果我们要使用
更新:(u,foo,bar)=>bar(foo.count)
我们最终作为一个道具传入,不需要设置器。因为
ProxyProvider
每个提供程序都会在依赖项更改时更新;这是我们想要的。但主要区别是
bar
提供程序中存储的每个值都将丢失,如果不通过最后一个参数并被使用(
)这是以前的状态。
class ProductsProvider with ChangeNotifier {
  List<Product> _items = [];
  String _authToken;
  void update(authToken, items) {
    _items = items;
    _authToken = authToken;
    notifyListeners();
  }
}
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,
  });
}