【问题标题】:How to show functions callback and errors on UI with bloc pattern in Flutter?如何在 Flutter 中使用 bloc 模式在 UI 上显示函数回调和错误?
【发布时间】:2019-03-25 15:38:42
【问题描述】:

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 上显示 bloc 的回调和错误。我不认为StreamBuilder 是唯一的解决方案。

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

有正确的方法吗?

提前谢谢你!!

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

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

    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 模式时使用回调。

    【讨论】:

    • 如果此答案解决了您的问题,请标记为正确。
    • 我希望有更多关于这个问题的答案。但无论如何,我将您的答案标记为正确。谢谢你的回答。
    • 如果我们从同一个 UI 调用两个 API 并且成功响应不同,上述解决方案将不起作用。
    【解决方案2】:

    根据 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!
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-11-20
      • 1970-01-01
      • 2020-03-11
      • 2020-09-03
      • 2023-03-12
      • 2020-11-07
      • 1970-01-01
      • 1970-01-01
      • 2020-08-16
      相关资源
      最近更新 更多