使用 RxSwift 触发的两个事件
Posted
技术标签:
【中文标题】使用 RxSwift 触发的两个事件【英文标题】:Two events fired with RxSwift 【发布时间】:2016-08-05 20:45:45 【问题描述】:嗨,我正在学习一些 RxSwift,我不明白为什么 makeLoginRequest 被调用两次...当登录正确时,我推送到另一个控制器,但 observable 仍然通知另一个事件,所以它推送两次下一个控制器..
在 viewModel 中的代码是这样的:
let userName : Driver<String>
let password : Driver<String>
var credentials : Driver<(String, String)>
return Driver.combineLatest(userName, password) usr, pwd in
return (usr, pwd)
var credentialValid : Driver<Bool>
let usrValid = userName
.map $0.rangeOfString("@") != nil
let pwdValid = password
.map $0.utf8.count > 5
return Driver.combineLatest(usrValid, pwdValid) usr, pwd in
return (usr && pwd)
func login() -> Observable<Login?>
return credentials.asObservable()
.observeOn(MainScheduler.instance)
.flatMapLatest credential -> Observable<Login?> in
return self.makeLoginRequest(user: credential.0, password: credential.1)
func makeLoginRequest(user user: String, password: String) -> Observable<Login?>
return self.provider
.request(APIProvider.Login(credentials: (user, password)))
.debug()
.mapObjectOptional(Login.self)
在控制器中
loginModel = LoginViewModel(provider: apiProvider! as! RxMoyaProvider<APIProvider>, userName: userTextField.rx_text.asDriver(), password: passwordTextField.rx_text.asDriver())
loginModel.credentialValid
.driveNext [unowned self] valid in
self.loginButton.enabled = valid
.addDisposableTo(disposeBag)
loginButton.rx_tap
.debug()
.flatMap( self.loginModel.login() )
.subscribeNext( login in
// handle here login data
)
.addDisposableTo(disposeBag)
谁能解释一下是怎么回事?
谢谢!
【问题讨论】:
【参考方案1】:您的问题可能在于您未显示的代码:userName
、password
或 provider
。此外,您包括了credentialsValid
,但它没有被使用。再说一遍,也许是该方法的某些内容,以及您如何在实际代码中使用它。
附带说明,您不应该在视图控制器中使用像这样嵌套的subscribeNext
。您应该使用flatMap
并仅订阅最终的Observable
。
看看你是否能想出一个代码示例来说明你的问题,我们可以实际运行,然后我们可以提供帮助。通过举这个例子,你可能会自己找出问题所在。
【讨论】:
我用您指出的凭据有效编辑了原始答案。什么是没有嵌套订阅Next的正确方法?问题是 makeLoginRequest 方法被调用了两次,它会推送一个视图控制器,如果执行两次它会推送两次,这是绝对错误的。 同样,您应该使用flatMap
而不是嵌套的subscribeNext
s,它将替换当前的Observable
,因此您只需订阅一次。您的编辑显示了您如何使用credentialValid
,但这看起来不是问题。我仍然相信未知的userName
、password
或provider
属性可能是问题所在。但同样,没有看到代码,我不能说。同样,您应该将此问题分解为可以在此处发布的简单内容。这样做你可能会找出问题所在,如果没有,我们至少可以运行它。
我知道如何在那里使用平面地图...但这不是解决方案。
您的问题过于依赖于您的整个应用程序。您可能需要分享您的项目回购才能真正得到答案。但是,这不适用于 ***。只是没有足够的信息来帮助你。以上是关于使用 RxSwift 触发的两个事件的主要内容,如果未能解决你的问题,请参考以下文章
RxSwift之订阅UITableViewCell里的按钮点击事件
带有 UITextFieldDelegate 的 RxSwift 控制事件