0

我正在构建一个包含讨论线程的应用程序。每个线程都有一个回复子集合,每个回复都有一个这样的反应图。因此,如果 JSON 化,每个 Thread 的子集合将如下所示:

{
  'replyDocument1': { 
    'authorName': 'Steve Dave', 
    'text': 'this is a reply', 
    'reactions': {'': ['userid1', 'userid2']}
  },
  ...
}

我正在尝试使用 Stream/Sink 设置来收听 Replies 子集合中的更改。即:只要有人向子集合中的任何回复添加反应,就重建回复列表视图。

这就是我到目前为止所得到的。模型和 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();
            },
          );
        });
  }
}

这可以很好地加载初始数据,如果我更改集合,例如:添加或删除回复,ListView 会重建。但是,如果我修改回复,例如:reactions在单个回复上更新地图,则不会发生任何事情。

我已经看到了向 QuerySnapshot 中的每个文档添加侦听器的解决方案,但我不清楚如何在这里实现它。

4

0 回答 0