flutter - StreamBuilder 的快照虽然通过 Stream 发送,但没有数据
问题描述
TL;DR:被添加的值由于StreamSink
某种未知原因被受尊敬的 StreamBuilder 覆盖initialValue
从表面上看,我的问题与 Github 上的这个问题类似,但唯一的区别是,我在控制台日志上看到两条语句,而不是获取单个值,其中一条具有正确的值,该值已添加到流中紧随其后的是传递给流构建器的初始值。
就我而言,我使用的是generic_bloc_provider
细化
我有一个 bloc udhariBloc.dart(第 99 行),它监听一个集合引用并将值添加到一些接收器。
void _fetchUdhari() {
Firestore.instance
.collection("Users 3.0")
.document("data")
.collection("udhari")
.where("participants", arrayContains: userBloc.phoneNumber)
.where("firstPartyDeleted", isEqualTo: false)
.snapshots()
.listen((QuerySnapshot snapshot) {
//Initialized these to zero because their
//value must be recalculated upon every change.
//These variables were initialized to zero(their default value) when declared.
_udhariList = List<UdhariClass>();
_totalDebit = 0;
_totalCredit = 0;
for (int i = 0; i < snapshot.documents.length; i++) {
_udhariList.add(UdhariClass.fromSnapshot(
snapshot: snapshot.documents[i],
userBloc: userBloc,
));
}
// Remove the udhari records where the participant is secondParty
// and secondParty has already deleted the record
_udhariList.removeWhere((UdhariClass udhari) {
return ((udhari.partyType == PartyType.SecondParty) &&
(udhari.secondPartyDeleted == true));
});
for (int i = 0; i < _udhariList.length; i++) {
if (_udhariList[i].udhariType == Udhari.Borrowed) {
_totalDebit += _udhariList[i].amount;
} else {
_totalCredit += _udhariList[i].amount;
}
}
//The correct values are calculated correctly,
//printed and added to respective sinks as well
print("Debit: $_totalDebit");
print("Credit: $_totalCredit");
print("List: ${_udhariList[0].context}");
_totalDebitSink.add(_totalDebit);
_totalCreditSink.add(_totalCredit);
_udhariListSink.add(_udhariList);
});
}
这里是流和它们的控制器
/// Stream controller for displaying total debit on dashboard
StreamController<double> _totalDebitController =
StreamController<double>.broadcast();
Stream<double> get totalDebitStream => _totalDebitController.stream;
StreamSink<double> get _totalDebitSink => _totalDebitController.sink;
/// Stream controller for displaying list of udhari
StreamController<List<UdhariClass>> _udhariListController =
StreamController<List<UdhariClass>>.broadcast();
Stream<List<UdhariClass>> get udhariListStream =>
_udhariListController.stream;
StreamSink<List<UdhariClass>> get _udhariListSink =>
_udhariListController.sink;
/// Stream controller for displaying total credit on dashboard
StreamController<double> _totalCreditController =
StreamController<double>.broadcast();
Stream<double> get totalCreditStream => _totalDebitController.stream;
StreamSink<double> get _totalCreditSink => _totalDebitController.sink;
这是我使用上述流的流生成器
StreamBuilder<double>(
initialData: udhariBloc.getTotalDebit,
stream: udhariBloc.totalDebitStream,
builder: (BuildContext context,
AsyncSnapshot<double> snapshot) {
print(
"============INSIDE DEBIT STREAM BLDR============");
print("Conn State: ${snapshot.connectionState}");
print("Has Data: ${snapshot.hasData}");
print("Data: ${snapshot.data}");
print("Has Error: ${snapshot.hasError}");
print("Error: ${snapshot.error}\n\n");
return Text("₹${snapshot.data.floor()}",
style: _textStyleFooter);
},
),
这些接收器随后会在Dashboard.dart内的 streamBuilders 中使用(第 145 行)。问题是,即使将数据添加到各个接收器(在本例中为_totalDebitSink
),值也不会在类内部的流构建器中更新Dashboard
。为了进一步调查,我_totalDebitStream
在 UdhariBloc 的构造函数内部附加了一个侦听器
totalDebitStream.listen((onData) {
print("CURRENT DEBIT: $onData");
}, onError: (error) {
print("Error listening Debit :$error");
}, onDone: () {
print("Done listening to Debit values");
});
每次值发生变化时,我都会在控制台中看到这个日志。
CURRENT DEBIT: 100
CURRENT DEBIT: 0
============INSIDE DEBIT STREAM BLDR============
Conn State: ConnectionState.active
Has Data: true
Data: 0.0
Has Error: false
Error: null
这里,100
是来自 Firestore 的更新值0
,是提供给 StreamBuilder 并分配给变量的 initialValue _totalDebit
,_totalCredit
。
我在dashboardBloc.dart(第 88 行)和Dashboard.dart (第 212 行)中使用了类似的技术,它就像一个魅力。
到目前为止,我还没有找到任何解决方案。
解决方案
最后,找到了解决方案。原来这是我的一个愚蠢的错误。我不小心将错误的流和接收器映射到了错误的控制器。在这种情况下,
Stream<double> get totalCreditStream => _totalDebitController.stream;
StreamSink<double> get _totalCreditSink => _totalDebitController.sink;
在这里,我不小心映射了totalCredtiStream
withdebitController
的流。
另外,感谢@pskink 指出。
推荐阅读
- java - 在 Java 中使用 scheduleAtFixedRate 遍历列表
- reactjs - 我应该如何导入 Gatsby 文件夹下的所有图像
- react-native-android - 反应本机当前位置不起作用
- php - 类型错误:传递给 Illuminate\Database\Grammar::parameterize() 的参数 1 必须是数组类型,给定整数
- c# - Unity 每旋转 1 度播放声音
- python - 如何从公司内网抓取数据?
- python - 一个旅游景点可以有多个主题。如何在 django 模型中实现这一点?
- typescript - 如何为 mapStateToProps 指定正确的返回类型?
- r - 在 R 数据框中按行查找最大绝对值
- azure - 如何在 azure 数据工厂中使用复制活动将常量值更新到 sql 表字段中