如何在 Flutter 中使用 bloc 模式在 UI 上显示函数回调和错误?



bloc.dart

class Bloc{
Bloc(){
additionalController.stream.listen(onAdd);
}
void dispose() async {
additionalController.close();
_itemAdd.close();
}
final additionalController = StreamController<Data>();
Sink<Data> get addItem => additionalController.sink;
Stream<String> get addGet => _itemAdd.stream;
final _itemAdd = BehaviorSubject<String>();
void onAdd(Data data) {
_addWork(data);
}
Future<Null> _addWork(Data data) async {
//work
}).whenComplete(() {
_itemAdd.add("complete work");
}).catchError((e) {
_itemAdd.addError("Error in Adding Data");
});
}
}

由于bloc应该只用于处理业务逻辑和共享,但错误处理部分与业务逻辑无关。

如何在UI上显示集团的回调和错误。我不认为StreamBuilder是唯一的解决方案。

如果我们使用StreamBuilder,这样,我们每次重建发生时都会重复向 bloc 发送回调,这是没有意义的。

有没有正确的方法可以做到这一点?

提前谢谢你!!

到目前为止,对我有用的是使用表示回调的接口。

abstract class AddItemDelegate {
void onSuccess();
void onError(String message);
}

然后在bloc中使用它,如下所示:

class Bloc {
AddItemDelegate _delegate;
// ...
Function addItem(Data item, AddItemDelegate delegate) => () {
_delegate = delegate;
additionalController.sink.add(item);
}
// ...
Future<Null> _addWork(Data data) async {
try {
final work = await //work...
_itemAdd.add("complete work");
_delegate?.onSuccess();
}
catch(e) {
final error = "Error in Adding Data";
_itemAdd.addError(error);
_delegate?.onError(error);
}
}
}

然后在StatefulWidget(或StatelessWidget(上执行以下操作:

class MyWidget extends StatelessWidget implements AddItemDelegate {
@override
void onSuccess() {
// e.g.: Show a dialog or navigate to other screen
}
@override
void onError(String message) {
// e.g.: Show an error dialog
}
@override
Widget build(BuildContext context) {
final bloc = // ...
final data = // ...
return MaterialButton(
child: Text("Add Item"), 
onPressed: bloc.addItem(data, this));
}
}

这样,可以在使用 BLoC 模式时使用回调。

根据 Dart 文档,这可以在 Dart 2.1 中使用 mixin 完成:

版本说明:Dart 2.1 中引入了对 mixin 关键字的支持。早期版本中的代码通常使用抽象类。有关 2.1 mixin 更改的详细信息,请参阅 Dart SDK 更改日志和 2.1 mixin 规范。

例:

mixin Music {
void play();
}
class Musician {
Music _delegate;
Musician(Music delegate){
_delegate = delegate;
}
play(){
_delegate.play();
}
}
class MyMusicWidget extends StatelessWidget with Music{
@override
Widget build(BuildContext context) {
return Container(
child: Text("Music")
);
}
@override
void play() {
// TODO: implement play
// Your code here!
}
}

最新更新