我正在尝试实现PaginatedDataTable
类。该类的构造函数中的必填字段是类DataTableSource
。查看flutter画廊示例here的材料部分中的数据表示例。 DataTableSource有一个名为List<Dessert> _desserts
的成员变量,其值经过硬编码。在我的实现中,我正在进行http调用并返回一些要解码的json。
List<Result> parseResults(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Result>((json) => Result.fromJson(json)).toList();
}
Future<List<Result>> fetchResults(http.Client client) async {
final response = await client.get('https://api.myjson.com/bins/j5xau');
// Use the compute function to run parseResults in a separate isolate
return compute(parseResults, response.body);
在我的DataTableSource类中,我不确定如何实例化列表。
`final List<Result> results = fetchResults(http.Client);`
之所以无法编译,是因为fetchResults()
返回了Future。如果我将返回类型更改为将来的类型,results
确实可以编译,但是我需要将返回的json类型设为List
,以便可以使用sort
等方法。应该如何转换未来的清单。
答案 0 :(得分:2)
在您的DataTableSource
类中,只需删除results
变量。然后,在build
函数中,您可以使用FutureBuilder
小部件,如下所示:
FutureBuilder<List<Result>>(
future: fetchResults(http.Client),
builder: (BuildContext context, AsyncSnapshot<List<Result>> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('Press button to start.');
case ConnectionState.active:
case ConnectionState.waiting:
return Text('Awaiting result...');
case ConnectionState.done:
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
return Text('Result: ${snapshot.data}');
}
return null; // unreachable
},
)
请注意,snapshot.data
现在是List<Result>
,当它是一个硬编码值时,您可以像以前一样使用它。
修改:
如果您不想使用FutureBuilder
,则建议您使用一个函数,该函数可以在http调用完成时基本上修改results
的值。这是我的意思的示例:
让DessertDataSource
在其构造函数中使用List<Result>
来定义results
的值,如下所示:
class DessertDataSource extends DataTableSource {
final List<Result> results;
DessertDataSource(this.results);
// rest of the class
}
在_DataTableDemoState
中,使_dessertsDataSource
不再是最终的,并将其初始值更改为DessertDataSource([])
。另外,添加一个布尔值,指示何时已加载数据。
class _DataTableDemoState extends State<DataTableDemo> {
// other fields!
DessertDataSource _dessertsDataSource = DessertDataSource([]);
bool isLoaded = false;
然后将以下功能添加到_DataTableDemoState
。布尔值确保我们只进行一次http调用。
Future<void> getData() async {
final results = await fetchResults(http.Client);
if (!isLoaded) {
setState(() {
_dessertsDataSource = DessertDataSource(results);
isLoaded = true;
});
}
}
最后,在按下按钮或其他触发器时,或者可能只是在构建功能开始时,调用该功能。
@override
Widget build(BuildContext context) {
getData();
return MYWidget();
}
然后,每当从http调用返回数据时,小部件都会自动使用新数据进行更新。