1

嗨,我在 BLoC 类中使用 BehaviorSubject。我面临的主要问题是即使在调用之后drain()close()最终值仍然保留在主题中。我怎样才能重置它?

完整项目链接:https ://github.com/SAGARSURI/Goals

这是我的代码。即使在对其调用和方法之后,也始终返回_title最终值:_goalMessagedrain()close()

class GoalsBloc {
  final _repository = Repository();
  final _title = BehaviorSubject<String>();
  final _goalMessage = BehaviorSubject<String>();
  final _showProgress = BehaviorSubject<bool>();

  Observable<String> get name => _title.stream.transform(_validateName);

  Observable<String> get goalMessage =>
      _goalMessage.stream.transform(_validateMessage);

  Observable<bool> get showProgress => _showProgress.stream;

  Function(String) get changeName => _title.sink.add;

  Function(String) get changeGoalMessage => _goalMessage.sink.add;

  final _validateMessage = StreamTransformer<String, String>.fromHandlers(
      handleData: (goalMessage, sink) {
    if (goalMessage.length > 10) {
      sink.add(goalMessage);
    } else {
      sink.addError(StringConstant.goalValidateMessage);
    }
  });

  final _validateName = StreamTransformer<String, String>.fromHandlers(
      handleData: (String name, sink) {
    if (RegExp(r'[!@#<>?":_`~;[\]\\|=+)(*&^%0-9-]').hasMatch(name)) {
      sink.addError(StringConstant.nameValidateMessage);
    } else {
      sink.add(name);
    }
  });

  void submit(String email) {
    _showProgress.sink.add(true);
    _repository
        .uploadGoal(email, _title.value, _goalMessage.value)
        .then((value) {
      _showProgress.sink.add(false);
    });
  }

  void extractText(var image) {
    _repository.extractText(image).then((text) {
      _goalMessage.sink.add(text);
    });
  }

  Stream<DocumentSnapshot> myGoalsList(String email) {
    return _repository.myGoalList(email);
  }

  Stream<QuerySnapshot> othersGoalList() {
    return _repository.othersGoalList();
  }

  //dispose all open sink
  void dispose() async {
    await _goalMessage.drain();
    _goalMessage.close();
    await _title.drain();
    _title.close();
    await _showProgress.drain();
    _showProgress.close();
  }

  //Convert map to goal list
  List mapToList({DocumentSnapshot doc, List<DocumentSnapshot> docList}) {
    if (docList != null) {
      List<OtherGoal> goalList = [];
      docList.forEach((document) {
        String email = document.data[StringConstant.emailField];
        Map<String, String> goals =
            document.data[StringConstant.goalField] != null
                ? document.data[StringConstant.goalField].cast<String, String>()
                : null;
        if (goals != null) {
          goals.forEach((title, message) {
            OtherGoal otherGoal = OtherGoal(email, title, message);
            goalList.add(otherGoal);
          });
        }
      });
      return goalList;
    } else {
      Map<String, String> goals = doc.data[StringConstant.goalField] != null
          ? doc.data[StringConstant.goalField].cast<String, String>()
          : null;
      List<Goal> goalList = [];
      if (goals != null) {
        goals.forEach((title, message) {
          Goal goal = Goal(title, message);
          goalList.add(goal);
        });
      }
      return goalList;
    }
  }

  //Remove item from the goal list
  void removeGoal(String title, String email) {
    return _repository.removeGoal(title, email);
  }
} 
4

2 回答 2

4

您可以将其值显式设置为 null。不知道这是否是好的做法,但它工作得很好。

void drainStream(){ _title.value = null; }
于 2019-03-25T09:51:13.107 回答
0

尝试_goalMessage.done——它将强制流完成,然后丢失数据。

于 2021-09-08T15:51:30.133 回答