flutter - 无法通过 ScanStreamTransformer 正确检索模型
问题描述
我正在尝试使用在 Flutter 中实现逻辑的ItemModel
流从我的存储库中检索一个类。BLoC
问题是ItemModel
找到但未检索到。因此触发了另一个循环并尝试返回一个不同的对象,该对象不在小部件上检索。
样本输出:
I/flutter ( 4520): trying to get 25314126 from cache
I/flutter ( 4520): 25314126 in transformer
I/flutter ( 4520): 25314126 found !! returning: {id: 25314126, type: story, by: xucheng, time: 1607172267, text: , parent: null, kids: [25314805,25314781,25314684,25314664], dead: 0, deleted: 0, url: https://bitbashing.io/std-visit.html, score: 24, title: std::visit is everything wrong with modern C++ (2017), descendants: 4}
I/flutter ( 4520): ----------item to find: 25314126 and found: Instance of 'ItemModel'
I/flutter ( 4520): returned item Instance of 'ItemModel'
在这里找到并检索了正确的对象,但在 UI 上没有收到,因此立即进行另一个搜索:
I/flutter ( 4520): trying to get 25314805 from cache
I/flutter ( 4520): 25314805 found !! returning: {id: 25314805, type: comment, by: vasama, time: 1607178963, text: We got here because adding library features is a lot easier and less risky than adding language features. Work on pattern matching [1] is ongoing, but the bar for entry for a language feature is much higher and as such takes a longer time.<p>1. <a href="http://wg21.link/p1371" rel="nofollow">http://wg21.link/p1371</a>, parent: 25314126, kids: [], dead: 0, deleted: 0, url: null, score: null, title: null, descendants: 0}
I/flutter ( 4520): ----------item to find: 25314805 and found: Instance of 'ItemModel'
I/flutter ( 4520): returned item Instance of 'ItemModel'
这不是我要检索的对象!!!
总是显示“正在加载 1”字符串
这是我的主要Widget
class NewsDetail extends StatelessWidget{
final int itemId;
NewsDetail({ this.itemId}) ;
@override
Widget build(BuildContext context) {
final bloc = CommentsProvider.of(context);
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Detail'),
),
body: buildBody(bloc),
);
}
Widget buildBody(CommentsBloc bloc){
return StreamBuilder(
stream: bloc.itemWithComments,
builder:
(context, AsyncSnapshot<Map<int,Future<ItemModel>>> snapshot){
if (!snapshot.hasData){
return Text('Loading 1');
}
final itemFuture = snapshot.data[itemId];
return FutureBuilder(
future: itemFuture,
builder: (context,AsyncSnapshot<ItemModel> itemSnapshot){
if(!itemSnapshot.hasData){
return Text('Loading 2');
}
return buildTitle(itemSnapshot.data);
}
);
},);
}
这表明有问题stream: bloc.itemWithComments,
这是我的 BLOC 课程:
class CommentsBloc{
final _repository = Repository();
final _commentsFetcher = PublishSubject<int>();
final _commentsOutput = BehaviorSubject<Map<int,Future<ItemModel>>>();
//Streams
get itemWithComments => _commentsOutput.stream;
//Sink
Function(int) get fetchItemWithComments => _commentsFetcher.sink.add;
CommentsBloc(){
_commentsFetcher.stream.transform(_commentsTransformer()).pipe(_commentsOutput);
}
_commentsTransformer (){
return ScanStreamTransformer(
(cache,int id,index){
cache[id] = _repository.fetchItem(id);
print('$id in transformer');
cache[id].then((ItemModel item){
item.kids.forEach((kidId)=>fetchItemWithComments(kidId));
});
},
<int,Future<ItemModel>>{},
);
}
dispose(){
_commentsFetcher.close();
_commentsOutput.close();
}
}
这是我在Repository
课堂上获取物品的方式
List<Source> sources = <Source>[
newsDbProvider,
NewsApiProvider(),
];
List<Cache> caches = <Cache>[
newsDbProvider,
];
Future<ItemModel> fetchItem(int id) async{
ItemModel item;
var source;
for(source in sources) {
item = await source.fetchItem(id);
print('----------item to find: $id and found: ${item}');
if(item!=null){
break;
}
}
for(var cache in caches) {
if(cache!=source) {
cache.addItem(item);
}
}
print('returned item ${item}');
return item;
}
即使每次都返回一个 Instance 为什么是
snapshot.hasData
false?
另请注意,小部件仅通过 using方法以正确的 id调用一次。我完全错过了什么?onTap
解决方案
即使我使用fetchItemWithComments
来下沉物品,我仍然必须在ScanStreamTransformer
_commentsTransformer (){
return ScanStreamTransformer<int,Map<int,Future<ItemModel>>>(
(Map<int,Future<ItemModel>>cache,int id,index){
print(index);
cache[id] = _repository.fetchItem(id);
cache[id].then((ItemModel item){
item.kids.forEach( (kidId) => fetchItemWithComments(kidId) );
});
return cache; //was missing this
},
<int,Future<ItemModel>>{},
);
}
这已经困扰我好几天了,我检查了所有内容,但找不到任何东西,所以如果你正在使用ScanStreamTransformer
课程
永远有一个
return
声明
推荐阅读
- css - CSS 媒体查询图像加载
- android - 如何在 Android 中为内容观察者或提供者注册您的主机名作为提供者?
- git - 尝试 git merge 中止没有任何错误
- php - 如何使用 Laravel 连接三个表并保持数据完整性
- javascript - JavaScript - 如何强制当前窗口处于活动状态?
- javascript - 在 eCharts 热图中显示字符串值
- sql - 将表连接到子查询
- java - 针对静态方法的“target()”切入点的 AspectJ 警告“Xlint:adviceDidNotMatch”
- python - 使用 scipy 对数正态分布拟合具有小值的数据,然后在 matplotlib 中显示
- java - 如何将 Java 8 安装到 Google Compute Debian 8 实例上?