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

时间:2017-05-04 18:31:23

标签: ios iphone swift reactive-programming rx-swift

我对RxSwift相对较新,并且正在努力实现我开发的最佳实践。

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

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

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

伪代码

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

alertSubscriptions

    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)

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

1 个答案:

答案 0 :(得分:2)

我碰巧写了一篇关于这个主题的文章: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)
    }
}

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

例如,上面的函数可以是视图控制器中按下按钮的flatMapped,或者添加到更复杂的Observable管道中。