我正在学习 udemy 上的 Flutter 和 Dart 课程,但它有点过时(2-3 年)。正在构建的应用程序应该从 thehackernews api 获取新闻和新闻详细信息。我目前使用 StreamBuilder
来检索新闻 item
的详细信息以及评论。以下代码不会读取对流的更改:
import 'package:flutter/material.dart';
import 'package:news/src/models/item_model.dart';
import 'package:news/src/blocs/comments_provider.dart';
import 'dart:async';
class NewsDetail extends StatelessWidget {
final int itemId;
NewsDetail({required this.itemId});
Widget build(context) {
final bloc = CommentsProvider.of(context);
return Scaffold(
appBar: AppBar(
title: Text('News Title'),
),
body: buildBody(bloc),
);
}
Widget buildBody(CommentsBloc bloc) {
return StreamBuilder(
stream: bloc.itemWithComments,
builder: (context, AsyncSnapshot<Map<int, Future<ItemModel?>>> snap) {
if (!snap.hasData) {
return Text('Loading 1'); // <---- Gets stuck here !!!!!!
}
final itemFuture = snap.data![itemId];
return FutureBuilder(
future: itemFuture,
builder: (context, AsyncSnapshot<ItemModel?> itemSnapshot) {
if (!itemSnapshot.hasData) {
return Text('Loading 2');
}
return Text('${itemSnapshot.data!.title}');
});
},
);
}
}
这里是集团:
import 'package:rxdart/rxdart.dart';
import '../models/item_model.dart';
import '../repositories/repository.dart';
import 'dart:async';
class CommentsBloc {
final _repository = Repository();
final _commentsFetcher = PublishSubject<int>();
final _commentsOutput = BehaviorSubject<Map<int, Future<ItemModel?>>>();
// Stream getters
Stream<Map<int, Future<ItemModel?>>> get itemWithComments =>
_commentsOutput.stream;
// Sink getters
Function(int) get fetchItemWithComments => _commentsFetcher.sink.add;
CommentsBloc() {
_commentsFetcher.stream
.transform(_commentsTransformer())
.pipe(_commentsOutput);
}
_commentsTransformer() {
return ScanStreamTransformer<int, Map<int, Future<ItemModel?>>>(
(cache, int id, index) {
final items = _repository.fetchItem(id);
cache[id] = items.then((ItemModel? item) {
item.kids!.forEach((kidId) => fetchItemWithComments(kidId));
});
return cache;
},
<int, Future<ItemModel>>{},
);
}
dispose() {
_commentsFetcher.close();
_commentsOutput.close();
}
}
供应商:
import 'package:flutter/material.dart';
import 'package:news/src/blocs/comments_bloc.dart';
export 'package:news/src/blocs/comments_bloc.dart';
class CommentsProvider extends InheritedWidget {
final CommentsBloc bloc;
CommentsProvider({required Key key, required Widget child})
: bloc = CommentsBloc(),
super(key: key, child: child);
bool updateShouldNotify(_) => true;
static CommentsBloc of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<CommentsProvider>()!.bloc;
}
}
我放置了一些打印件,我可以看到获取 kids
的调用已完成,数据已保存到 sqlite 中,但这并未反映在流中,因此未显示任何数据。
有什么想法吗?
注意:我正在使用 rxdart: ^0.27.1
和 sdk: ">=2.12.0 <3.0.0"