RxSwift - onNext не вызывается при проверке UITextField после нажатия кнопки - PullRequest
0 голосов
/ 05 апреля 2020

Получилась довольно большая проблема - имейте форму с парой полей ввода и хотели бы проверить те, которые используют RxSwift. Все отлично работает, когда я редактирую текст, но просто не работает, когда я хочу проверить эти поля после нажатия кнопки или даже просто связать эти поля с button.rx.isEnabled, любая помощь будет принята. Код ниже (смешанный с некоторыми комментариями):

ViewController:
func setupBindings() {
        self.emailInputField.inputTf
            .rx.text.orEmpty
            .bind(to: self.presenter.emailInputFieldPublishSubject)
            .disposed(by: self.disposeBag)
        self.messageInputField.inputTv
            .rx.text.orEmpty
            .bind(to: self.presenter.messageInputFieldPublishSubject)
            .disposed(by: self.disposeBag)
        self.presenter.validateEmail()
            .subscribe(onNext: { [weak self] errorMessage in
                self?.emailInputField.error = errorMessage
            })
            .disposed(by: self.disposeBag)
        self.presenter.validateMessage()
            .subscribe(onNext: { [weak self] errorMessage in
                self?.messageInputField.error = errorMessage
            })
            .disposed(by: self.disposeBag)

// Everything above works fine, error message is set properly as soon as the user taps the input field - that's correct

// rx.tap action is called, flatMap is called, but then subscribe(onNext) is not called, looks like onNext is not emitted or so

        self.submitButton.rx.tap.flatMap { [weak self] (_) -> Observable<String?> in
            guard let context = self else { return Observable.just(nil) }
            return context.presenter.validateEmail()
        }
        .subscribe(onNext: { (value) in
            SwiftyBeaver.debug("onNext \(value ?? "")")
        }, onError: { (error) in
            SwiftyBeaver.debug("onError \(error)")
        }, onCompleted: {
            SwiftyBeaver.debug("onCompleted")
        }, onDisposed: {
            SwiftyBeaver.debug("onDisposed")
        })
        .disposed(by: self.disposeBag)
}
ViewModel:
    let emailInputFieldPublishSubject = PublishSubject<String>()
    let messageInputFieldPublishSubject = PublishSubject<String>()
    func validateEmail() -> Observable<String?> {
        return emailInputFieldPublishSubject.debug().map { $0.validateEmail() }
    }
    func validateMessage() -> Observable<String?> {
        return messageInputFieldPublishSubject.map { $0.validate(minLength: 3, maxLength: 1024) }
    }


// Also have "validateForm" method to validate the whole form after tapping "submitButton", but it doesn't work from the same reason. Don't worry about consent validation, it works just the same.

    func validateForm() -> Observable<Bool> {
        return Observable.combineLatest(self.validateConsent(),
                                        self.validateEmail(),
                                        self.validateMessage())
            .map { (consentError, emailError, messageError) in
                return consentError.isBlank && emailError.isBlank && messageError.isBlank
            }
    }

Схожу с ума, любая помощь очень ценится.

1 Ответ

0 голосов
/ 06 апреля 2020

Хорошо, мне удалось это исправить самостоятельно:

Прежде всего мне пришлось связать не ControlProperty текстового поля, а вместо этого я должен был сделать его Observable (asObservable()), и тогда это сработало , Но это еще не все - была проблема, потому что вызов rx.text создает другую подписку, и это может привести к зависанию приложений и т. Д. c.

(как параметры) вот так: Observable.just(emailInputField.inputTf.text) и тогда все заработало:)

...