我有多个textFields,他们的验证标准非常简单。
为了简化问题陈述,我们假设标准是
名字至少应包含一个字符,
姓氏应至少有一个字符
和年龄应该大于0
假设我有一个验证器操作
validatorAction = Action<Void,Bool> {
return Single<Bool>.create(subscribe: { (single) -> Disposable in
if self.firstName.text?.count ?? 0 > 0 && self.lastName.text?.count ?? 0 > 0 && self.age.text?.count ?? 0 > 0 {
single(.success(true))
}
else {
single(.success(false))
}
return Disposables.create()
})
}
我希望每次在任何文本字段中的字符更改时执行此操作,因此我将此操作绑定到UIControlEvents.editingChanged
self.firstName.rx.bind(to: validatorAction, controlEvent: self.firstName.rx.controlEvent(UIControlEvents.editingChanged)){ (textField) -> Void in
return Void()
}
self.lastName.rx.bind(to: validatorAction, controlEvent: self.lastName.rx.controlEvent(UIControlEvents.editingChanged)){ (textField) -> Void in
return Void()
}
self.age.rx.bind(to: validatorAction, controlEvent: self.age.rx.controlEvent(UIControlEvents.editingChanged)) { (textField) -> Void in
return Void()
}
最后,我希望操作控制按钮的启用和禁用状态
validatorAction.elements
.asObservable()
.startWith(false)
.asDriver(onErrorJustReturn: false)
.drive(self.submitButton.rx.isEnabled)
.disposed(by: self.disposeBag)
不幸的是,尽管代码工作正常,但每次执行validatorAction
时,textField都会失去焦点。这会导致巨大的用户体验问题。
我向RxAction仓库提出issue并获得了回复
你好!听起来你有点滥用封闭性 传递给Action初始化器。您将尝试使用完整版 初始化程序Action(enabledIf:,workFactory :)分离出一个 用于启用/禁用操作的闭包,以及另一个用于返回的闭包 无论你想做什么工作都可以观察到。然后你可以绑定 对按钮的操作,它将处理启用/禁用它。 查看自述文件以获取更多信息,并告诉我们它是如何进行的。
但是关于如何使用它并没有太大的帮助。有人可以展示如何使用Actions来实现预期行为的具体代码。
答案 0 :(得分:2)
在我看来,更好的方法是使用文本字段绑定变量并对变量进行验证。
var firstName = Variable<String>("")
var lastName = Variable<String>("")
var age = Variable<String>("")
tfFirstName.rx.text.orEmpty.bind(to: firstName).disposed(by: rx_disposeBag)
tfLastName.rx.text.orEmpty.bind(to: lastName).disposed(by: rx_disposeBag)
tfAge.rx.text.orEmpty.bind(to: age).disposed(by: rx_disposeBag)
然后你可以这样做验证:
var isValid : Observable<Bool>{
return Observable.combineLatest( firstName.asObservable(), lastName.asObservable(), age.asObservable()){ (fname, lname, userAge) in
return fname.count > 0 && lname.count > 0 && userAge.count > 0
}
}
最后,您可以像这样绑定Action submitButton:
submitButton.rx.action = Action(enabledIf: isValid, workFactory:{input in
//Action code here
})
我希望能回答你的问题。