调用StreamController.sink.add时,StreamBuilder没有反应

时间:2019-03-27 12:28:40

标签: dart flutter stream bloc stream-builder

在Flutter应用程序中,我有一个屏幕专门用于编辑对象列表。当您按下编辑按钮时,将弹出一个模态,允许您编辑对象值。当您关闭模型时,将通过BLoC刷新列表。但是,当调用刷新列表的方法时,没有任何反应。

bloc.dart
class Bloc {

  final _provider = ModelProvider();
  final _controller = StreamController<List<Model>>();

  Stream<List<Model>> get models => _controller.stream;

  void getModels() async {
    final List<Model> models = await _provider.readAll();
    _controller.sink.add(models);
  }

  Future<int> saveModel(Model model) async {
    final int id = await _provider.write(model);
    return id;
  }

}
list_screen.dart
class ListScreen extends StatelessWidget {

  final bloc = Bloc();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          // SliverAppBar ...
          StreamBuilder<List<Model>>(
            stream: bloc.models,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (context, index) =>
                      ListTile(
                        title: Text(snapshot.data[index].name),
                        onPressed: () => _editModel(context),
                      ),
                ),
              } else {
                bloc.getModels();
                return Container();
              }
            }          
          ),
        ],
      ),
    );
  }

  void _editModel(BuildContext context) async {
    final Model edited = await showDialog(
      context: context,
      builder: (context) => EditModal(),
    );
    if (edited != null) {
      await bloc.saveModel(edited);
      bloc.getModels();
    }
  }

}

我知道数据已正确存储在数据库中,因为如果我转到上一个屏幕,然后返回到编辑屏幕,则会更新数据。谁能帮助我找出为什么StreamBuilder不重建的原因?

2 个答案:

答案 0 :(得分:0)

可能的问题是,在保存后调用bloc.getModels时,或者在save方法给出错误并破坏了未运行getModels的方法时,您没有放置等待状态

答案 1 :(得分:0)

希望这会对某人有所帮助:对我来说,问题是,当我更新列表时,它实际上是存储在字段中的相同引用。每次创建一个新列表并且不将列表存储在同一字段中都会解决该问题。从该问题中我们看不到您的ModelProvider内部,但看起来可能是同一问题。

此内容在第一次之后没有更新:

deserialising

现在通过删除字段,它会更新StreamBuilder:

class MiniaturePaintsBloc implements Bloc {

  List<MiniaturePaint> _miniaturePaints;

  final _controller = StreamController<List<MiniaturePaint>>.broadcast();

  Stream<List<MiniaturePaint>> get miniaturePaintsStream => _controller.stream;

  void fetchMiniaturePaints() async {
    QuerySnapshot querySnapshot =
        await Firestore.instance.collection("MiniaturePaints").getDocuments(source: Source.serverAndCache);
    _miniaturePaints = querySnapshot.documents.map((doc) => _docToMiniaturePaint(doc)).toList();
    _controller.sink.add(_miniaturePaints);
  }

  //rest of BloC code here
}