使用复选框按钮验证表单 RxCocoa/RxSwift
validate form with checkbox button RxCocoa/RxSwift
我需要用单选按钮验证表单,但我做不到,我分享我的代码:
我的看法:
private func registerForm() {
tvUserName.rx.text.map { [=11=] ?? "" }.bind(to: viewModel.userNamePublishSubject).disposed(by: disposeBag)
tvEmail.rx.text.map { [=11=] ?? "" }.bind(to: viewModel.emailPublishSubject).disposed(by: disposeBag)
tvPassword.rx.text.map { [=11=] ?? "" }.bind(to: viewModel.passwordPublishSubject).disposed(by: disposeBag)
tvRepeatPassword.rx.text.map { [=11=] ?? "" }.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)
}
我的视图模型:
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
}
我已经验证了表单,但我还需要用户接受条款和条件才能启用“下一步”按钮。
在设计响应式系统时,您需要考虑因果关系。每个可观察的链应该关注一个单一的效果,并根据需要为该效果引入尽可能多的原因。就像一个函数有几个传入的参数和 returns 一个值。
在这种情况下,你的效果是btnNext.rx.isEnabled
。你必须考虑是什么导致这种影响发生变化?这是我如何编写的示例:
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 { [=10=].count >= 5 },
email.map { [=10=].isEmail() },
password.map { [=10=].count >= 5 },
Observable.combineLatest(password, repeatPassword) { [=10=] == },
checkBox.scan(false) { state, _ in !state }.startWith(false)
]
)
.map { [=10=].allSatisfy { [=10=] } }
}
注意这里的视图模型是多么简单。这是 isNextButtonEnabled
函数。它可以很容易地进行测试,但它是如此简单,以至于您甚至可能觉得没有必要进行测试。确定是否启用下一个按钮的所有条件都集中在一个地方以便于理解。不需要一堆 PublishSubjects。它更容易阅读和理解。
我需要用单选按钮验证表单,但我做不到,我分享我的代码:
我的看法:
private func registerForm() {
tvUserName.rx.text.map { [=11=] ?? "" }.bind(to: viewModel.userNamePublishSubject).disposed(by: disposeBag)
tvEmail.rx.text.map { [=11=] ?? "" }.bind(to: viewModel.emailPublishSubject).disposed(by: disposeBag)
tvPassword.rx.text.map { [=11=] ?? "" }.bind(to: viewModel.passwordPublishSubject).disposed(by: disposeBag)
tvRepeatPassword.rx.text.map { [=11=] ?? "" }.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)
}
我的视图模型:
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
}
我已经验证了表单,但我还需要用户接受条款和条件才能启用“下一步”按钮。
在设计响应式系统时,您需要考虑因果关系。每个可观察的链应该关注一个单一的效果,并根据需要为该效果引入尽可能多的原因。就像一个函数有几个传入的参数和 returns 一个值。
在这种情况下,你的效果是btnNext.rx.isEnabled
。你必须考虑是什么导致这种影响发生变化?这是我如何编写的示例:
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 { [=10=].count >= 5 },
email.map { [=10=].isEmail() },
password.map { [=10=].count >= 5 },
Observable.combineLatest(password, repeatPassword) { [=10=] == },
checkBox.scan(false) { state, _ in !state }.startWith(false)
]
)
.map { [=10=].allSatisfy { [=10=] } }
}
注意这里的视图模型是多么简单。这是 isNextButtonEnabled
函数。它可以很容易地进行测试,但它是如此简单,以至于您甚至可能觉得没有必要进行测试。确定是否启用下一个按钮的所有条件都集中在一个地方以便于理解。不需要一堆 PublishSubjects。它更容易阅读和理解。