每次过滤器更改时,下面的流预计都会更新。但附加的侦听器会触发两次,一次使用旧值,另一次使用新值,但没有指示哪个是哪个。
我已经确认
tourFilterPovider
仅触发一次,因此问题似乎出在 filteredOrderStream
的定义中。
如何将其更改为仅使用新的过滤列表触发?
流媒体提供商:
@riverpod
Stream<List<Order>> filteredOrdersStream(FilteredOrdersStreamRef ref) {
final repository = ref.watch(ordersRepositoryProvider);
final filter = ref.watch(tourFilterProvider);
if (filter.isEmpty) {
return repository.watchOrders();
} else {
return repository.watchOrders().map((orders) {
return orders.where((order) => filter.contains(order.tour)).toList();
});
}
}
@Riverpod(keepAlive: true)
OrdersRepository ordersRepository(OrdersRepositoryRef ref) {
return OrdersRepository(FirebaseFirestore.instance);
}
class OrdersRepository {
...
Stream<List<Order>> watchOrders() => queryOrders()
.orderBy(Order.CREATEDAT_KEY, descending: true)
.snapshots()
.map((snapshot) => snapshot.docs.map((doc) => doc.data()).toList());
}
消费者:
ref.listen<AsyncValue>(filteredOrdersStreamProvider, (_, state) async {
if (state.hasValue) {
// PROBLEM: this is called with old and new values on every filter change
final filteredOrders = state.value;
// do something
}
});
问题不在于提供者,而在于我的听众。
state.hasValue
并不表示状态已加载完成。 文档说了这么多。这意味着我的侦听器在加载期间使用旧值触发一次,并在加载完成后使用新值触发第二次。
将侦听器中的检查更改为
if (!state.isLoading && state.hasValue)
解决了问题。