2017-03-17 59 views
1

我是RxSwift的新手,我發現的所有示例都處理簡單案例。Rx Swift:複雜的TextFields驗證

我正在嘗試對我的文本框進行表單驗證。 我的自定義TextField類有一個方法isValid()和一個regexpisValid返回值基於regexp屬性。

到目前爲止,我寫了下面的:

let valids = [mLastName, mFirstName, mEmailField].map { 
    $0.rx.text.map { 
     text -> Bool in 
     // I want more complex logic here 
     // Like return field.isValid() 
     return text!.characters.count > 0 
    } 
}  

let _ = Observable.combineLatest(valids) { iterator -> Bool in 
    return iterator.reduce(true, { $0 && $1 }) 
}.subscribe(onNext: { allValid in 
    ///update button according to AllValid 
}) 

有誰知道如何更新的代碼庫中的第一Observable<Bool>根據我的isValid()方法,而不是text!.characters.count

回答

1

我找到了答案我。問題出在第一張地圖上,我不應該使用匿名參數。

請參見:

let valids = [mLastName, mFirstName, mEmailField].map { field in 
    field.rx.text.map({ _ in return field.isValid() }) 
} 

_ = Observable.combineLatest(valids) { iterator -> Bool in 
    return iterator.reduce(true, { return $0 && $1 }) 
}.bindTo(self.mValidateButton.rx.isEnabled) 
3

可能有許多方法可以做到這一點。

您可以使用filter改造rx.text可觀察到在自定義TextField類:

var isTextValid: Observable<Bool> { 
    return rx.text.filter { _ in 
     return self.isValid() 
    } 
} 

那麼你就可以從combineLatest所有文本字段合併isTextValid


您還可以從自定義文本字段中提取驗證邏輯(也許您甚至不需要自定義文本字段)。

優點:

  • 驗證可能會更容易進行單元測試
  • 您可以輕鬆地重複使用在不同的地方驗證在你的應用程序(例如,用於UITextView如果你曾經使用它)。

一個驗證器類的草案:

class TextValidator { 
    var input: Observable<String> 
    var regex: NSRegularExpression 

    init(input: Observable<String>, regex: NSRegularExpression) { 
     self.input = input 
     self.regex = regex 
    } 

    func validate() -> Observable<Bool> { 
     return input.map { text in 
      //return true if regex matches the text 
     } 
    }  
} 

然後你就可以按如下方式使用它:如果你想要寫的驗證單元測試(

let mailValidator = TextValidator(input: mLastName.rx.text, regex: /* actual regex*/) 
let firstNameValidator = TextValidator(input: mFirstName.rx.text, regex: ...) 



let _ = Observable.combineLatest(mailValidator.validate(), firstName.validate(), ...) 
// and so on 

現在,你可能應該這樣做),你可以簡單地通過Observable.just("Some value")作爲inputTextValidator並驗證validate()返回的Observable的功能。