Flutter 颤振Futurebuilder使用“防止重建”;“旧数据”;
我对颤振是个新手,我知道这个问题已经被问过好几次了,但我的问题稍微有点不同(我想)。我已经读了,然后解决方案包括使用,但我仍然在挣扎 我的情况如下。我有一个类似于Airbnb的“搜索结果”页面,用户输入一个位置和一些日期,然后返回一组结果。结果通过API从get调用中检索,搜索结果小部件使用Futurebuilder小部件构建 用户当然应该能够编辑他们的搜索,当他们这样做时,他们导航到不同的页面,更改位置,然后返回搜索结果页面。问题是当他们这样做时,API会被调用两次,Futurebuilder会重新构建。因此,例如,如果原始搜索是“LA”,而新搜索是“纽约”,Futurebuilder首先重建“LA”,然后重建“纽约”,而它应该只运行“纽约”搜索。如果我再次将位置更改为“旧金山”,它将重建3次,例如“洛杉矶”,然后是“纽约”,然后是“旧金山”,而它应该只为旧金山运行。如果我再换4次等等 我希望Futurebuilder重新构建,因为搜索已更改,但它应该只为新搜索运行,而不是首先为每个“历史”搜索运行。我不知道如何做到这一点 我的代码:Flutter 颤振Futurebuilder使用“防止重建”;“旧数据”;,flutter,flutter-provider,flutter-navigation,flutter-futurebuilder,Flutter,Flutter Provider,Flutter Navigation,Flutter Futurebuilder,我对颤振是个新手,我知道这个问题已经被问过好几次了,但我的问题稍微有点不同(我想)。我已经读了,然后解决方案包括使用,但我仍然在挣扎 我的情况如下。我有一个类似于Airbnb的“搜索结果”页面,用户输入一个位置和一些日期,然后返回一组结果。结果通过API从get调用中检索,搜索结果小部件使用Futurebuilder小部件构建 用户当然应该能够编辑他们的搜索,当他们这样做时,他们导航到不同的页面,更改位置,然后返回搜索结果页面。问题是当他们这样做时,API会被调用两次,Futurebuilder
class SearchResults extends StatelessWidget{
final String location;
SearchResults(this.location);
Future<void> _refreshSearch(BuildContext context) async{
await Provider.of<Hosts>(context, listen: false).loadHosts(location);
}
@override
Widget build(BuildContext context) {
return Column(children: <Widget>[
FiltersRow(),
Expanded(
child: Consumer<Hosts>(builder: (ctx, localhosts, child) {
//this print statement tells me that the widget runs all "historical" searches in addition to the new search
print('$location - results widget');
return localhosts.hosts.length == 0 ?
FutureBuilder(
future: Provider.of<Hosts>(context, listen: true).loadHosts(location),
builder: (ctx, dataSnapshot) {
if(dataSnapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else {
if(dataSnapshot.error != null) {
return Text('An error occurred');
} else {
return
RefreshIndicator(
onRefresh: () => _refreshSearch(context),
child:
ListView.builder(
itemCount: localhosts.hosts.length,
itemBuilder: (context, index) => ChangeNotifierProvider.value(
value: localhosts.hosts[index],
child:
SearchCard()
)
)
);
}
}
}) : RefreshIndicator(
onRefresh: () => _refreshSearch(context),
child:
ListView.builder(
itemCount: localhosts.hosts.length,
itemBuilder: (context, index) => ChangeNotifierProvider.value(
value: localhosts.hosts[index],
child: SearchCard()
)
)
);
})
),
]);
}
}
类搜索结果扩展了无状态小部件{
最终管柱位置;
搜索结果(此位置);
Future\u refreshSearch(BuildContext上下文)异步{
等待Provider.of(上下文,侦听:false).loadHosts(位置);
}
@凌驾
小部件构建(构建上下文){
返回列(子项:[
FiltersRow(),
扩大(
子:使用者(生成器:(ctx、本地主机、子){
//这个print语句告诉我,除了新的搜索之外,小部件还运行所有“历史”搜索
打印(“$location-results小部件”);
返回localhosts.hosts.length==0?
未来建设者(
future:Provider.of(context,listen:true).loadHosts(location),
建造商:(ctx、dataSnapshot){
if(dataSnapshot.connectionState==connectionState.waiting){
返回中心(子项:CircularProgressIndicator());
}否则{
如果(dataSnapshot.error!=null){
返回文本(“发生错误”);
}否则{
返回
刷新指示器(
onRefresh:()=>\u refreshSearch(上下文),
儿童:
ListView.builder(
itemCount:localhosts.hosts.length,
itemBuilder:(上下文,索引)=>ChangeNotifierProvider.value(
值:localhosts.hosts[索引],
儿童:
搜索卡()
)
)
);
}
}
}):刷新指示器(
onRefresh:()=>\u refreshSearch(上下文),
儿童:
ListView.builder(
itemCount:localhosts.hosts.length,
itemBuilder:(上下文,索引)=>ChangeNotifierProvider.value(
值:localhosts.hosts[索引],
儿童:搜索卡()
)
)
);
})
),
]);
}
}