Flutter StreamBuilder 未收到数据

时间:2021-06-03 18:26:23

标签: flutter dart

我正在学习 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.1sdk: ">=2.12.0 <3.0.0"

0 个答案:

没有答案