2017-05-04 3 views
1

Ich bin relativ neu in RxSwift und versuche Best Practices zu implementieren, während ich mich entwickle.RxSwfit: Ist es eine schlechte Übung, ein vorgestelltes View-Controller-View-Modell zu abonnieren?

Auf meinem Home-View-Controller muss ich einen benutzerdefinierten Alarmansicht-Controller präsentieren, wo der Benutzer Text in ein Textfeld eingibt und auf bestätigen klickt. Angenommen, der Text ist gültig, wird die Warnung beendet und ein neuer View-Controller wird gedrückt.

Um die Verwendung eines Callbacks oder Delegaten zu vermeiden, stelle ich den Alarmansicht-Controller vor, dann abonniert mein HomeView-Controller das Textfeld des Alarmansicht-Controllers und bestätigt die Schaltfläche.

Ist es eine schlechte Übung, einen anderen View-Controller zu abonnieren?

Pseudocode:

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) 

Ich habe diesen Code getestet und es funktioniert ohne Probleme.

Antwort

2

Ich habe zufällig einen Artikel über dieses Thema geschrieben: https://medium.com/@danielt1263/encapsulating-the-user-in-a-function-ec5e5c02045f Der Artikel verwendet Promises, aber das gleiche Verfahren würde, und IMHO sollten, wenn Rx verwendet werden.

Ich denke, so etwas wie dies besser wäre:

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

von in einer Sequenz Emitterfunktion den gesamten Code enthält (dh eine Funktion, die eine beobachtbare zurückgibt,) Sie öffnen die Tür für das Hinzufügen der Funktion eine Kette von Observablen.

Zum Beispiel könnte die obige Funktion aus einem Knopfdruck in Ihrem View-Controller entfernt werden oder auf andere Weise zu einer beteiligteren Observable-Pipeline hinzugefügt werden.

Verwandte Themen