flutter - 有没有办法让多个 FutureBuilders 使用 ChangeNotifier 中的同一个未来?
问题描述
我有一个类(扩展 ChangeNotifier - Provider 包),它有一个返回 Future 的函数。我想要做的是拥有它,以便我的 UI 代码中的多个 futureBuilder 可以从该函数接收值,但不必每个 FutureBuilder 调用该函数一次。
但是,我使用的每个 FutureBuilder 都会一次又一次地运行该函数本身。我知道必须有一种方法可以通过 Provider 包公开 Future 本身,但我似乎无法弄清楚如何。
这是扩展 ChangeNotifier 并具有未来的类:
class ApiService extends ChangeNotifier {
CurrencyTicker _data;
CurrencyTicker get getdata => _data;
set setdata(CurrencyTicker data) {
_data = data;
}
Future<CurrencyTicker> fetchBaseData() async {
final response =
await http.get(API_URL_HERE); // url removed for stackoverflow
if (response.statusCode == 200) {
print('1 call logged');
setdata = CurrencyTicker.fromJson(json.decode(response.body));
return CurrencyTicker.fromJson(json.decode(response.body));
} else {
throw Exception('Request failed: ' + response.statusCode.toString());
}
}
}
这是 UI 代码(它只是一个 FutureBuilder):
class MyBody extends StatelessWidget {
const MyBody({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final provider = Provider.of<ApiService>(context);
return Center(
child: FutureBuilder(
future: provider.fetchBaseData(),
initialData: CurrencyTicker().price,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(snapshot.data.company),
],
);
} else {
return LinearProgressIndicator();
}
},
),
);
}
}
我没有在小部件树的“顶层”包含 MultiProvider,因为我不明白为什么必须这样做。我没有包含 CurrencyTicker 类的模型。如有必要,我可以提供这两个。
将不胜感激任何意见在这里
解决方案
您不想直接在使用者的 build 方法中进行 HTTP 调用。
您应该公开一个属性,而不是在 ChangeNotifier 上公开一个方法:
class MyNotifier with ChangeNotifier {
Future<Foo> foo;
}
这foo
是一个存储你上次fetchData
调用结果的变量。
然后,根据您的需要,您可以:
fetchData
如果立即需要,在构造函数中调用
class MyNotifier with ChangeNotifier {
MyNotifier() {
foo = fetchData();
}
Future<Foo> foo;
}
- 使用自定义 getter 延迟加载它:
class MyNotifier with ChangeNotifier {
Future<Foo> _foo;
Future<Foo> get foo => _foo ??= fetchData();
}
推荐阅读
- java - 如何从 Java 中读取 proto3 自定义选项
- java - 宾果游戏 Java
- android - Xamarin 应用无法识别任何蓝牙设备 (Plugin.BluetoothLE)
- node.js - 在没有密码提示的情况下运行 sudo 命令
- java - 移动 3 个对象但保持对齐的公共方法
- android - 屏幕关闭时如何保持相机预览打开?
- java - 配置应用程序以 log4j2 故障登录 ActiveMQ
- sql - 检查 varchar 列是否只有字母字符
- rabbitmq - Airflow Worker - KeyError: u'No such transport: ampq
- php - PHP - Behat - 页面对象扩展 - 致命错误:未捕获的 ArgumentCountError:函数 FeatureContext::__construct() 的参数太少