编辑:对更新的问题的答案,以下为原文
目前还不清楚是什么
A,
B,
C和
D在你原来的问题主张。原来那是 模特 。
我目前的想法是,用
MultiProvider/ 包装您的应用程序
ProxyProvider以提供 服务 ,而不是模型。
不知道如何加载数据(如果有的话),但是我假定了一种异步获取船队的服务。如果您的数据是通过零件/模型通过不同的服务加载的(而不是一次全部)加载的,则可以将其添加到中,
MultiProvider并在需要加载更多数据时将其插入适当的小部件中。
下面的示例是完整的功能。为了简单起见,并且由于您以更新
name为例进行了询问,所以我仅设置了该属性设置器
notifyListeners()。
import 'package:flutter/material.dart';import 'package:provider/provider.dart';main() { runApp( MultiProvider( providers: [Provider.value(value: Service())], child: MyApp() ) );}class MyApp extends StatelessWidget { @override Widget build(context) { return MaterialApp( home: Scaffold( body: Center( child: Consumer<Service>( builder: (context, service, _) { return FutureBuilder<Fleet>( future: service.getFleet(), // might want to memoize this future builder: (context, snapshot) { if (snapshot.hasData) { final member = snapshot.data.aircrafts[0].crewMembers[1]; return ShowCrewWidget(member); } else { return CircularProgressIndicator(); } } ); } ), ), ), ); }}class ShowCrewWidget extends StatelessWidget { ShowCrewWidget(this._member); final CrewMember _member; @override Widget build(BuildContext context) { return ChangeNotifierProvider<CrewMember>( create: (_) => _member, child: Consumer<CrewMember>( builder: (_, model, __) { return GestureDetector( onDoubleTap: () => model.name = 'Peter', child: Text(model.name) ); }, ), ); }}enum Manufacturer { Airbus, Boeing, Embraer}class Fleet extends ChangeNotifier { List<Aircraft> aircrafts = [];}class Aircraft extends ChangeNotifier { Manufacturer aircraftManufacturer; double emptyWeight; double length; List<Seat> seats; Map<int,CrewMember> crewMembers;}class CrewMember extends ChangeNotifier { CrewMember(this._name); String _name; String surname; String get name => _name; set name(String value) { _name = value; notifyListeners(); }}class Seat extends ChangeNotifier { int row; Color seatColor;}class Service { Future<Fleet> getFleet() { final c1 = CrewMember('Mary'); final c2 = CrewMember('John'); final a1 = Aircraft()..crewMembers = { 0: c1, 1: c2 }; final f1 = Fleet()..aircrafts.add(a1); return Future.delayed(Duration(seconds: 2), () => f1); }}运行该应用程序,等待2秒钟以加载数据,然后您将在该地图中看到ID为1的机组人员“约翰”。然后双击文本,它应该更新为“ Peter”。
如您所见,我正在使用服务的顶级注册(
Provider.value(value:Service()))和模型的本地注册(
ChangeNotifierProvider<CrewMember>(create: ...))。
我认为这种架构(具有合理数量的模型)应该是可行的。
关于本地级别的提供程序,我觉得它有点冗长,但是可能有一些方法可以使它更简短。同样,为模型提供一些代码生成库,这些模型具有用setter通知更改的功能。
(您有C#背景吗?我已将您的类固定为符合Dart语法。)
让我知道这是否适合您。
如果要使用提供程序,则必须使用提供程序构建依赖关系图。
(您可以选择构造函数注入,而不是setter注入)
这有效:
main() { runApp(MultiProvider( providers: [ ChangeNotifierProvider<D>(create: (_) => D()), ChangeNotifierProxyProvider<D, C>( create: (_) => C(), update: (_, d, c) => c..d=d ), ChangeNotifierProxyProvider<C, B>( create: (_) => B(), update: (_, c, b) => b..c=c ), ChangeNotifierProxyProvider<B, A>( create: (_) => A(), update: (_, b, a) => a..b=b ), ], child: MyApp(), ));}class MyApp extends StatelessWidget { @override Widget build(context) { return MaterialApp( title: 'My Flutter App', home: Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[Text( 'Current selected Color',),Consumer<D>( builder: (context, d, _) => Placeholder(color: d.color)), ], ), ), floatingActionButton: FloatingActionButton( onPressed: () => Provider.of<D>(context, listen: false).color = Colors.black, tooltip: 'Increment', child: Icon(Icons.arrow_forward), ), ), ); }}此应用可根据您
A,
B,
C和
D类。
您的示例不使用代理,因为它仅使用
D没有依赖关系的代理。但是您可以看到Provider通过以下示例正确连接了依赖项:
Consumer<A>( builder: (context, a, _) => Text(a.b.c.d.runtimeType.toString())),
它将打印出“ D”。
ChangeColor()因为没有打电话而没有工作
notifyListeners()。
无需在此之上使用有状态的小部件。



