我正在构建一个包含讨论线程的应用程序。每个线程都有答复的子集合,每个答复都有这样的反应图。因此,如果经过JSON化,则每个线程的子集合将如下所示:
{
'replyDocument1': {
'authorName': 'Steve Dave',
'text': 'this is a reply',
'reactions': {'?': ['userid1', 'userid2']}
},
...
}
我正在尝试使用流/接收器设置来侦听“答复”子集合中的更改。即:只要有人向子集合中的任何“答复”添加“反应”,就重建“答复” ListView。
这是我到目前为止所掌握的。模型和RepliesApi类没有做任何令人兴奋的事情,因此我将它们省略了。
class RepliesBloc {
final String threadId;
RepliesApi _api;
final _controller = StreamController<List<Reply>>.broadcast();
Stream<List<Reply>> get stream =>
_controller.stream.asBroadcastStream();
StreamSink<List<Reply>> get sink => _controller.sink;
RepliesBloc(this.threadId) {
this._api = RepliesApi(this.threadId);
this
._api
.collectionReference
.getDocuments()
.asStream()
.listen(_repliesUpdated);
this._api.collectionReference.snapshots().listen(_repliesUpdated);
}
void _repliesUpdated(QuerySnapshot querySnapshot) {
List<Reply> replies = _api.fromQuerySnapshot(querySnapshot);
this.sink.add(replies);
}
void dispose() {
_controller.close();
}
}
class ThreadReplyList extends StatefulWidget {
ThreadReplyList(this.threadId, {Key key}) : super(key: key);
final String threadId;
@override
_ThreadReplyListState createState() => _ThreadReplyListState();
}
class _ThreadReplyListState extends State<ThreadReplyList> {
RepliesBloc _bloc;
@override
void initState() {
super.initState();
this._bloc = RepliesBloc(this.widget.threadId);
}
@override
Widget build(BuildContext context) {
dev.log('starting ThreadReplyList.build', name: "ThreadReplyList.build");
return StreamBuilder(
stream: this._bloc.stream,
builder: (context, snapshot) {
return ListView.separated(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return ThreadReply(snapshot.data[index]);
},
separatorBuilder: (BuildContext context, int index) {
return SizedBox.shrink();
},
);
});
}
}
这样可以很好地加载初始数据,如果我更改了集合,例如:添加或删除Reply,则ListView会重建。但是,如果我修改了一个Reply,例如:在单个Reply上更新reactions
地图,则什么也没有发生。
我已经看到了将侦听器添加到QuerySnapshot中的每个文档的解决方案,但是我不清楚如何在此处实现。