2016-08-05 7 views
0

Hallo Ich lerne etwas RxSwift, ich verstehe nicht, warum makeLoginRequest zweimal aufgerufen wird ... wenn Login korrekt ist, schiebe ich zu einem anderen Controller, aber das Observable benachrichtigt noch ein anderes Ereignis so schieben sie es zweimal am nächsten Controller ..Zwei Ereignisse gefeuert mit RxSwift

im Ansichtsmodell der Code ist dies:

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) 
} 

und in der Steuerung

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) 

Wer kann erklären, was los ist?

Danke!

Antwort

1

Ihr Problem liegt wahrscheinlich bei Code, den Sie nicht angezeigt haben: userName, password oder provider. Außerdem haben Sie credentialsValid eingeschlossen, aber es wird nicht verwendet. Also noch einmal, vielleicht etwas mit dieser Methode und wie Sie es in Ihrem tatsächlichen Code verwenden.

Als Randnotiz sollten Sie subscribeNext nicht so verschachtelt wie in Ihrem View-Controller verwenden. Sie sollten flatMap verwenden und nur das letzte Observable abonnieren.

Sehen Sie, wenn Sie mit einem Codebeispiel kommen, das Ihr Problem zeigt, das wir tatsächlich ausführen können, und dann können wir helfen. Sie werden wahrscheinlich selbst herausfinden, was falsch ist, indem Sie dieses Beispiel machen.

+0

Ich habe die ursprüngliche Antwort mit CredentialsValid bearbeitet, auf die Sie hinweisen. Was ist der richtige Weg, um keinen verschachtelten SubscribeNext zu haben? Das Problem ist, dass die Methode makeLoginRequest zweimal aufgerufen wird und einen View-Controller verschiebt. Wenn sie zweimal ausgeführt wird, wird sie zweimal gedrückt und es ist absolut falsch. – jerrygdm

+0

Auch hier sollten Sie 'flatMap' anstelle von verschachtelten' subscribeNext's verwenden, die das aktuelle 'Observable' ersetzen, so dass Sie nur einmal abonnieren können. Ihre Änderung zeigt, wie Sie 'credentialValid' verwenden, aber das scheint nicht das Problem zu sein. Ich glaube immer noch, dass die unbekannten Eigenschaften 'userName',' password' oder 'provider' das Problem sein könnten. Aber wieder, ohne Code zu sehen, kann ich nicht sagen. Und wieder sollten Sie dieses Problem auf etwas Einfaches reduzieren, das Sie hier veröffentlichen können. Sie werden wahrscheinlich herausfinden, was falsch ist, und wenn nicht, können wir es zumindest ausführen. – solidcell

+0

Ich finde heraus, wie ich Flatmap dort verwenden kann ... aber es ist nicht die Lösung. – jerrygdm

Verwandte Themen