我正在使用StreamProvider
包中的provider
来自Firebase Firestore的流,如下面的代码片段所示(DatabaseService.streamVehicles
只是实际查询的包装函数Firestore)。
为响应用户事件,locationId
变量将设置为不同的ID,以在Firestore查询中进行过滤。但是,无论何时locationId
发生更改,组件都将重建,但是传递给create
参数的函数将不会再次调用,因此新的locationId
值将不会传递给查询与流仍然相同,未经过滤的流。每当locationId
更改时,如何确保创建新的流?
class HomePage extends StatefulWidget {
static final String id = 'home';
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final CupertinoTabController _tabController =
CupertinoTabController(initialIndex: 0);
String locationId;
void setLocationId(String newId) {
this.setState(() {
locationId = newId;
});
}
@override
Widget build(BuildContext context) {
print("Building homepage");
return Consumer<User>(
builder: (context, user, _) {
return StreamProvider<List<Vehicle>>(
create: (context) => DatabaseService.streamVehicles(
user.organization.id,
locationId: locationId,
),
catchError: (ctx, err) {
print("Error in stream");
print(err);
return [];
},
child: CupertinoTabScaffold(
controller: _tabController,
tabBar: CupertinoTabBar(
activeColor: kHighlightColor,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.collections),
title: Text('Vehicles'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.settings),
title: Text('Settings'),
),
],
),
tabBuilder: (BuildContext context, int index) {
switch (index) {
case 0:
return VehiclesPage(
locationId: locationId, setLocationId: setLocationId);
case 1:
return SettingsPage();
}
return null;
},
),
);
},
);
}
}
streamVehicles
的{{1}}方法定义如下。
DatabaseService
答案 0 :(得分:0)
如果您想在发生任何事情时创建一个新的流,然后呈现该流的内容,我通常会将流存储在小部件的状态:
void setLocationId(String newId) {
this.setState(() {
locationId = newId;
});
// TODO: determine the new stream, and set that in the state too
}
然后在您的build
方法中,您使用状态中的流,而不是直接使用服务中的流。
答案 1 :(得分:0)
使用StreamProvider.family创建每个ID唯一的新流提供程序。