2017-03-17 8 views
1

私はRxSwiftに新規であり、私が見つけたすべての例は単純なケースを扱っています。Rx Swift:Complex TextFields Validation

私はテキストフィールドのフォーム検証をしようとしています。 私のカスタムTextFieldクラスには、メソッドisValid()regexpがあります。 isValidの返品は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 
}) 

誰もが、私は答えを見つけた代わりにtext!.characters.count

答えて

1

の最初のObservable<Bool>が私のisValid()法に基づいてベースにコードを更新する方法を知っています私自身。最初のマップで問題が発生しました。匿名パラメータを使用しないでください。

参照:

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

はそれを行うには、多くの方法は、おそらくあります。

あなたは、カスタムTextFieldクラスで観察rx.textを変換するためにfilterを使用することができます。

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")inputからTextValidatorに単純に渡して、validate()が返すObservableが何であるかを確認してください)。