RxSwift:订阅呈现的视图控制器视图模型是不好的做法吗?

RxSwfit: Is it bad practice to subscribe to a presented view controllers view model?

我对 RxSwift 比较陌生,我正在尝试在开发过程中实施最佳实践。

在我的主页视图控制器上,我必须提供一个自定义警报视图控制器,用户可以在其中将文本输入文本字段并点击确认。假设文本有效,警报将被解除并推送一个新的视图控制器。

为了避免使用回调或委托,我提供了警报视图控制器,然后我的主视图控制器订阅了警报视图控制器的文本字段和确认按钮。

订阅不同的视图控制器是不好的做法吗?

伪代码

    let alert = viewModel.textFieldAlert()
    present(alert)
    alertSubscriptions(alert)

警报订阅:

    alert.textField.rx.text.subscribe(onNext: { [weak self] text in
        self?.viewModel.numberOfItems.value = text ?? ""
    }).addDisposableTo(disposeBag)

    alert.confirmButton.rx.tap.subscribe(onNext: { [weak self] _ in
        guard self != nil else { return }
        if !self!.viewModel.validText { return }
        alert.dismiss()
        self!.alertConfirmed()
    }).addDisposableTo(disposeBag)

我已经测试了这段代码,它没有任何问题。

我碰巧写了一篇关于这个主题的文章:https://medium.com/@danielt1263/encapsulating-the-user-in-a-function-ec5e5c02045f这篇文章使用了 Promises,但是在使用 Rx 时应该执行相同的过程,恕我直言。

我觉得像这样会更好:

extension UIViewController {

    func infoAlert(title: String, message: String, isValidInput: @escaping (String) -> Bool) -> Observable<String> {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)

        let confirm = PublishSubject<Void>()
        let confirmed = UIAlertAction(title: "OK", style: .default) { (action) in
            confirm.onNext()
        }

        let text = PublishSubject<String>()
        alert.addTextField { textField in
            textField.placeholder = "Enter Data"
            _ = textField.rx.text.orEmpty.bind(to: text)
        }

        _ = text.map(isValidInput)
            .bind(to: confirmed.rx.isEnabled)

        alert.addAction(confirmed)

        present(alert, animated: true, completion: nil)
        return confirm.withLatestFrom(text)
    }
}

通过将所有代码包含在一个序列发射器函数中(即 returns 一个可观察对象的函数),您打开了将函数添加到可观察对象链的大门。

例如,上面的函数可以通过视图控制器中的按钮按下进行平面映射,或者以其他方式添加到更复杂的 Observable 管道中。