簡體   English   中英

如何更好地結合使用相同發布主題的這兩個值

[英]How can I better combine this 2 values that consume the same Publish Subjects

我正在學習RxSwift

我已經建立了一個視圖模型來響應ViewController綁定。

isValid檢查用戶名和密碼是否存在,然后啟用我的登錄按鈕。

didTapLoginSubject在登錄按下時觸發,使用credentialsObservable didTapLoginSubject的最新值將調用服務。

所有這些都可以按照我的意願進行,但是我覺得在isValidcredentialsObservable isValid工作方面還沒有進行一些優化。

我看到重復的代碼,並且感覺可以寫得更好,但是我不確定怎么做。

我想也許是這樣的:

    private(set) lazy var isValid: Observable<Bool> = {
        return Observable.withLatestFrom(self.credentialsObservable).map { $0.count > 0 && $1.count > 0 }
    }()

但這顯然行不通。


import Foundation
import RxSwift
import RxCocoa

class LoginViewModel: NSObject {
    private(set) lazy var username = PublishSubject<String>()
    private(set) lazy var password = PublishSubject<String>()
    private(set) lazy var didTapLoginSubject = PublishSubject<Void>()

    private(set) lazy var isValid: Observable<Bool> = {
        return Observable.combineLatest(self.username, self.password, resultSelector: { $0.count > 0 && $1.count > 0 })
    }()

    private var credentialsObservable: Observable<(String, String)> {
        return Observable.combineLatest(self.username, self.password, resultSelector: { ($0, $1) })
    }

    private let disposeBag = DisposeBag()

    override init() {
        super.init()

        didTapLoginSubject
            .withLatestFrom(credentialsObservable)
            .subscribe(
                onNext: login,
                onError: onError
        ).disposed(by: disposeBag)
    }

    private func login(_ username: String, _ password: String) {
        print(username, password)
    }

    private func onError(_ error: Error) {
        print(error.localizedDescription)
    }
}

僅當更改某些內容時,您的視圖才會獲得新的憑據(因為PublishSubjects以此方式工作)。 因此,在視圖訂閱視圖模型時將憑據存儲在BehaviorSubject並獲取最新狀態可能很有用。 如果您提供用戶名/密碼的某些概要文件狀態,則很有必要。

private lazy var credentials = BehaviorSubject<(String, String)?>(value: nil)

並在init中准備綁定:

Observable
    .combineLatest(username, password){ ($0, $1) }
    .bind(to: credentials)
    .disposed(by: disposeBag)

您還可以將存儲的憑據用於isValid檢查和didTapLoginSubject

var isValid: Observable<Bool> {
    return credentials
        .asObservable()
        .map({ (credentials) -> Bool in
            guard let credentials = credentials else {
                return false
            }
            return credentials.0.count > 0 && credentials.1.count > 0
        })
        .distinctUntilChanged()
}

didTapLoginSubject
    .withLatestFrom(credentials)
    .filterNil()
    .subscribe(
        onNext: login,
        onError: onError
    ).disposed(by: disposeBag)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM