2017-05-04 43 views
1

我對RxSwift相對較新,並試圖在開發時實施最佳實踐。RxSwfit:訂閱視圖控制器視圖模型是不好的做法嗎?

在我的家庭視圖控制器上,我必須提供一個自定義警報視圖控制器,用戶在文本框中輸入文本並點擊確認。假設文本是有效的,警報將被解除,並推送新的視圖控制器。

爲避免使用回調或委託,我提供了警報視圖控制器,然後我的主視圖控制器訂閱了警報視圖控制器的文本框和確認按鈕。

訂閱不同的視圖控制器是不好的做法嗎?

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) 

我已經測試此代碼和它的作品沒有任何問題。

回答

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) 
    } 
} 

通過包含在一個序列發射體功能的所有代碼(即返回一個可觀察到的一個功能),你開門添加的功能一系列可觀察的事物。

例如,上面的函數可以在您的視圖控制器中按下按鈕的平面圖,或者添加到更多涉及的Observable管道中。