我有一个类(扩展了 ChangeNotifier - Provider 包),它有一个返回 Future 的函数。我想要做的是让我的 UI 代码中的多个 futureBuilder 可以从这个函数接收值,而不必为每个 FutureBuilder 调用一次该函数。
但是,我使用的每个 FutureBuilder 都会一次又一次地运行函数本身。我知道必须有一种方法可以通过 Provider 包公开 Future 本身,但我似乎无法弄清楚如何。
这是扩展 ChangeNotifier 的类,其中包含 future :
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 类的模型。如果需要,我可以提供这两个。
非常感谢这里的任何输入
最佳答案
您不想直接在消费者的构建方法中执行 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();
}
关于flutter - 有没有办法让多个 FutureBuilder 从 ChangeNotifier 使用同一个 future ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57663229/