简体   繁体   English

使用复选框按钮 RxCocoa/RxSwift 验证表单

[英]validate form with checkbox button RxCocoa/RxSwift

I need to validate the form with a radio button, but I can't do it, I share my code:我需要使用单选按钮验证表单,但我做不到,我分享了我的代码:

My View:我的看法:

“看法”

private func registerForm() {
    tvUserName.rx.text.map { $0 ?? "" }.bind(to: viewModel.userNamePublishSubject).disposed(by: disposeBag)
    tvEmail.rx.text.map { $0 ?? "" }.bind(to: viewModel.emailPublishSubject).disposed(by: disposeBag)
    tvPassword.rx.text.map { $0 ?? "" }.bind(to: viewModel.passwordPublishSubject).disposed(by: disposeBag)
    tvRepeatPassword.rx.text.map { $0 ?? "" }.bind(to: viewModel.repeatPasswordPublishSubject).disposed(by: disposeBag)
    viewModel.formLoginNativaIsValid().bind(to: btnNext.rx.isEnabled).disposed(by: disposeBag)
    
    checkBoxOutlet.rx.tap
    .scan(false) { lastValue, _ in
        return !lastValue
    }
    .bind(to: btnNext.rx.isEnabled)
    .disposed(by: disposeBag)
}

My ViewModel:我的视图模型:

“视图模型”

let userNamePublishSubject = PublishSubject<String>()
let emailPublishSubject = PublishSubject<String>()
let passwordPublishSubject = PublishSubject<String>()
let repeatPasswordPublishSubject = PublishSubject<String>()

func formLoginNativaIsValid() -> Observable<Bool> {
    return Observable.combineLatest(userNamePublishSubject.asObserver(),
        emailPublishSubject.asObserver(),
        passwordPublishSubject.asObserver(),
        repeatPasswordPublishSubject.asObserver()).map { userName, email, password, repeatPassword in
            return self.validateRegister(userName: userName, email: email, password: password,
                                         repeatPassword: repeatPassword)
    }.startWith(false)
}

private func validateRegister(userName: String, email: String, password: String, repeatPassword: String) -> Bool {
    return userName.count >= 5 && email.isEmail() && password.count >= 5 && repeatPassword.count >= 5 && password == repeatPassword
}

I have validated the form, but I also need the user to accept the terms and conditions for the "next" button to be enabled.我已经验证了表单,但我还需要用户接受条款和条件才能启用“下一步”按钮。

When designing a reactive system, you need to think about cause and effect.在设计反应式系统时,您需要考虑因果关系。 Each observable chain should focus on a single effect and bring in as many causes as needed for that effect.每个可观察的链都应该专注于一个单一的结果,并根据该结果的需要引入尽可能多的原因。 Just like a function has several parameters passed in and returns a single value.就像一个函数传入多个参数并返回单个值一样。

In this case, your effect is btnNext.rx.isEnabled .在这种情况下,您的效果是btnNext.rx.isEnabled And you have to consider what causes that effect to change?你必须考虑是什么导致这种影响发生变化? Here is an example of how I would write it:这是我如何编写它的示例:

class View: UIView {
    weak var tvUserName: UITextView!
    weak var tvEmail: UITextView!
    weak var tvPassword: UITextView!
    weak var tvRepeatPassword: UITextView!
    weak var btnNext: UIButton!
    weak var checkBoxOutlet: UIButton!

    let disposeBag = DisposeBag()

    override func awakeFromNib() {
        super.awakeFromNib()

        isNextButtonEnabled(
            username: tvUserName.rx.text.orEmpty.asObservable(),
            email: tvEmail.rx.text.orEmpty.asObservable(),
            password: tvPassword.rx.text.orEmpty.asObservable(),
            repeatPassword: tvRepeatPassword.rx.text.orEmpty.asObservable(),
            checkBox: checkBoxOutlet.rx.tap.asObservable()
        )
        .bind(to: btnNext.rx.isEnabled)
        .disposed(by: disposeBag)
    }
}

func isNextButtonEnabled(username: Observable<String>, email: Observable<String>, password: Observable<String>, repeatPassword: Observable<String>, checkBox: Observable<Void>) -> Observable<Bool> {
    return Observable.combineLatest(
        [
            username.map { $0.count >= 5 },
            email.map { $0.isEmail() },
            password.map { $0.count >= 5 },
            Observable.combineLatest(password, repeatPassword) { $0 == $1 },
            checkBox.scan(false) { state, _ in !state }.startWith(false)
        ]
    )
    .map { $0.allSatisfy { $0 } }
}

Notice how simple your view model is here.请注意您的视图模型在这里是多么简单。 It's the isNextButtonEnabled function.它是isNextButtonEnabled函数。 It can be tested very easily but is so simple that you might not even feel the need to test.它可以很容易地进行测试,但又是如此简单,以至于您甚至可能觉得没有必要进行测试。 All the conditions that determine if the next button is enabled are gathered up in a single place for easy understanding.决定是否启用下一个按钮的所有条件都集中在一个地方,以便于理解。 No need for a bunch of PublishSubjects.不需要一堆 PublishSubjects。 It's a lot easier to read and understand.它更容易阅读和理解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM