RxSwift - 当点击按钮后验证UITextField时,没有调用onNext。

问题描述 投票:0回答:1

我遇到了一个很大的问题--我有一个有几个输入字段的表单,想用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
            }
    }

我不知道该怎么做,希望能得到帮助。

ios swift reactive-programming rx-swift
1个回答
0
投票

好吧,我自己解决了这个问题。

首先,我没有绑定文本字段的ControlProperty,而是把它变成了一个Observable(asObservable())然后它就工作了。但这还不是全部--还有一个问题,因为调用rx.text会产生另一个订阅,这可能会导致应用程序滞后等。

为了解决这个问题,我简单地将rx.text传递给 validateForm() 方法的观测值(作为参数)这样。Observable.just(emailInputField.inputTf.text) 然后就能正常工作了:)

© www.soinside.com 2019 - 2024. All rights reserved.