无法通过ScanStreamTransformer正确检索模型



我正试图使用在Flutter中实现BLoC逻辑的流从存储库中检索ItemModel类。

问题是ItemModel已找到但未检索到。因此,触发了另一个循环,并试图返回一个不同的Object,而该Object不是在Widgets上检索的。

样本输出:

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:&#x2F;&#x2F;wg21.link&#x2F;p1371" rel="nofollow">http:&#x2F;&#x2F;wg21.link&#x2F;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;
}

即使每次都返回一个实例,为什么snapshot.hasData为false

此外,请注意,通过使用onTap方法,使用正确的id,小部件仅被调用一次。我完全错过了什么?

即使我使用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语句

最新更新