我怎样才能让这个 Flutter Bloc 发送更新?
Posted
技术标签:
【中文标题】我怎样才能让这个 Flutter Bloc 发送更新?【英文标题】:How can I have this Flutter Bloc to send updates? 【发布时间】:2020-09-13 06:22:13 【问题描述】:我有这个 Flutter 块,它采用 Firebase 餐厅流,根据相对于用户的位置,将根据餐厅位置仅过滤最近的餐厅。它工作正常,但如果我想查看餐厅文件中的任何更改,我必须使用 RefreshIndicator 刷新。我错过了什么?提前致谢。
class NearestRestaurant
final String id;
final Restaurant restaurant;
final double distance;
NearestRestaurant(this.id, this.restaurant, this.distance);
class NearRestaurantBloc
final Future<List<Restaurant>> source;
final Position userCoordinates;
final _stream = StreamController<List<Restaurant>>();
NearRestaurantBloc(
this.source,
this.userCoordinates,
)
List<Restaurant> resList = List<Restaurant>();
source.then((rest)
rest.forEach((res) async
await Geolocator().distanceBetween(
userCoordinates.latitude,
userCoordinates.longitude,
res.coordinates.latitude,
res.coordinates.longitude,
).then((distance)
if (res.active && distance < res.deliveryRadius)
resList.add(res);
);
_stream.add(resList);
);
);
Stream<List<Restaurant>> get stream => _stream.stream;
void dispose()
_stream.close();
class RestaurantQuery extends StatefulWidget
@override
_RestaurantQueryState createState() => _RestaurantQueryState();
class _RestaurantQueryState extends State<RestaurantQuery>
NearRestaurantBloc bloc;
@override
Widget build(BuildContext context)
final database = Provider.of<Database>(context, listen: true);
final session = Provider.of<Session>(context);
final userCoordinates = session.position;
bloc = NearRestaurantBloc(
source: database.patronRestaurants(),
userCoordinates: userCoordinates,
);
return StreamBuilder<List<Restaurant>>(
stream: bloc.stream,
builder: (context, snapshot)
bool stillLoading = true;
var restaurantList = List<Restaurant>();
if (snapshot.connectionState == ConnectionState.active)
if (snapshot.hasData && snapshot.data.length > 0)
restaurantList = snapshot.data;
stillLoading = false;
return Scaffold(
appBar: AppBar(
title: Text(
'Restaurants near you',
style: TextStyle(color: Theme.of(context).appBarTheme.color),
),
elevation: 2.0,
),
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
body: RefreshIndicator(
onRefresh: () async
setState(()
);
,
child: RestaurantList(
nearbyRestaurantsList: restaurantList,
stillLoading: stillLoading,
),
),
);
,
);
@override
void dispose()
bloc.dispose();
super.dispose();
【问题讨论】:
【参考方案1】:在_RestaurantQueryState
下的build
方法中,您将在builder
方法之外返回scaffold
。最初,restaurantList
为空。因此,您不会生成列表。每当流更新时,您都会获取快照数据以更新restaurantList
。
问题出现在这里。即使restaurantList
已更新,小部件RestaurantList
也不会更新,因为它位于构建器方法之外。您可以使用以下代码。在这里,我们创建一个包含 RestaurantList
小部件的小部件。每当流更新时,小部件就会更新。
class _RestaurantQueryState extends State<RestaurantQuery>
NearRestaurantBloc bloc;
@override
Widget build(BuildContext context)
final database = Provider.of<Database>(context, listen: true);
final session = Provider.of<Session>(context);
final userCoordinates = session.position;
//////////////////////////////////
//initialize RestaurantList widget
//////////////////////////////////
Widget restaurantWidget = RestaurantList(
nearbyRestaurantsList: [],
stillLoading: false,
);
bloc = NearRestaurantBloc(
source: database.patronRestaurants(),
userCoordinates: userCoordinates,
);
return StreamBuilder<List<Restaurant>>(
stream: bloc.stream,
builder: (context, snapshot)
bool stillLoading = true;
var restaurantList = List<Restaurant>();
if (snapshot.connectionState == ConnectionState.active)
if (snapshot.hasData && snapshot.data.length > 0)
restaurantList = snapshot.data;
/////////////////////////////
//update the restaurant widget
//////////////////////////////
restaurantWidget = RestaurantList(
nearbyRestaurantsList: restaurantList,
stillLoading: stillLoading,
);
stillLoading = false;
return Scaffold(
appBar: AppBar(
title: Text(
'Restaurants near you',
style: TextStyle(color: Theme.of(context).appBarTheme.color),
),
elevation: 2.0,
),
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
///////////////////////////
//use the restaurant Widget
///////////////////////////
body: restaurantWidget,
),
);
,
);
【讨论】:
谢谢,Mohammed,但它没有用。餐厅更新仍未发布。【参考方案2】:我的错。我听的是未来而不是流。这是更新后的区块代码:
class NearestRestaurant
final String id;
final Restaurant restaurant;
final double distance;
NearestRestaurant(this.id, this.restaurant, this.distance);
class NearRestaurantBloc
final Stream<List<Restaurant>> source;
final Position userCoordinates;
final _stream = StreamController<List<Restaurant>>();
NearRestaurantBloc(
this.source,
this.userCoordinates,
)
List<Restaurant> resList = List<Restaurant>();
source.forEach((rest)
resList.clear();
rest.forEach((res) async
await Geolocator().distanceBetween(
userCoordinates.latitude,
userCoordinates.longitude,
res.coordinates.latitude,
res.coordinates.longitude,
).then((distance)
if (res.active && distance < res.deliveryRadius)
resList.add(res);
);
_stream.add(resList);
);
);
Stream<List<Restaurant>> get stream => _stream.stream;
【讨论】:
以上是关于我怎样才能让这个 Flutter Bloc 发送更新?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter BLoC:Cubits 比 BLoC 好吗?
React:我怎样才能让这个 React 组件写得更好更高效?