簡體   English   中英

RxSwift,RxCocoa - 驗證后寫入 TextField 時不調用

[英]RxSwift, RxCocoa - no called when writing TextField after validation

我是 RxSwift 和 RxCocoa 的新手,我需要任何學習建議

檢查 ID 驗證結果后,label 中沒有字

但它正在更新 label 並且在綁定 function 處沒有進入斷點

我的代碼有什么問題……?


  var disposeBag: DisposeBag = DisposeBag()
  let viewModel = ViewModel()

  override func viewDidLoad() {
        super.viewDidLoad()

        let input: Signal<String> = userIDTextField.rx.text.orEmpty
            .asSignal(onErrorSignalWith: .empty())
        let output: Driver<String> = viewModel.bind(input)
        
        disposeBag.insert(
            output.drive(userIDLabel.rx.text)
        )
  }
struct ViewModel {

  func checkUserIDFromDB(id: String) -> Signal<Bool> {
        return .just(false).asSignal()
  }
    
  func bind(_ input: Signal<String>) -> Driver<String> {
        let validState = input
            .map { _ in self.checkUserIDFromDB(id:)}
            .withLatestFrom(input)
        
        return validState.asDriver(onErrorDriveWith: .empty())
  }
}

這一行: .map { _ in self.checkUserIDFromDB(id:)}產生一個Signal<(String) -> Signal<Bool>>這可能不是你想要的。

我假設這里的目標是將輸入的字符串傳遞給網絡請求並等待它發出。 如果它發出true則將字符串發送到 label,否則什么也不做......

此外,讓我們通過使用Observable類型而不是 Signals 和 Drivers 來簡化事情:

final class ViewController: UIViewController {
    let userIDTextField = UITextField()
    let userIDLabel = UILabel()
    let disposeBag = DisposeBag() // this should be a `let` not a `var`
    let viewModel = ViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()
        let input = userIDTextField.rx.text.orEmpty
        let output = viewModel.bind(input.asObservable())
        disposeBag.insert(
            output.bind(to: userIDLabel.rx.text)
        )
    }
}

struct ViewModel {
    func checkUserIDFromDB(id: String) -> Observable<Bool> { .just(false) }

    func bind(_ input: Observable<String>) -> Observable<String> {
        input.flatMapLatest { id in  // Note this should be `flatMapLatest` not `map`
            Observable.zip(  // zip up the text with its response
                Observable.just(id),
                self.checkUserIDFromDB(id: id) // you weren't actually making the network call. This makes it.
                    .catchAndReturn(false) // if the call fails, emit `false`.
            )
        }
        .compactMap { $0.1 ? $0.0 : nil } // if the response is true, emit the text, else nothing
    }
}

我對這段代碼最大的擔憂是如果用戶繼續輸入會發生什么。 這將在用戶輸入的每個字符后觸發,這可能是很多網絡請求, flatMapLatest將取消不再需要的正在進行的請求,但仍然......考慮在 stream 中放置一個debounce以減少請求的數量。

這篇文章中了解更多關於flatMap不同版本的信息。

暫無
暫無

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

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