8

RxSwift/RxCocoa 2.0.0- beta 3 では、次の ViewModel を使用しています。

let someString = Variable("")

func isValidSomeString() -> Observable<Bool>  {

    if someString.value.characters.count == 0 {
        return just(false)
    }
    return just(true)
}   

ViewController のテキスト フィールドに someString を既にバインドしています。

someString (より適切な方法であればテキスト フィールド) が変更されるたびに、someString が有効かどうかに基づいてボタンを有効にする必要があります。

「Observable< Bool >」を使用してみましたが、別の道をたどり始めました。ViewController でこれを行うことができます。

    someViewModel.someString.subscribeNext { text -> Void in

        // could just someUIButton.enabled = someViewModel.isValidSomeString(text)

    }.addDisposableTo(disposeBag)

isValidSomeString(text) アプローチよりも冗長でない別の方法はありませんか? 既に、combineLatest を使用した Observable< Bool > を返す isValidLogin で素晴らしい成功を収めています。

4

2 に答える 2

9

Actionこの場合に使用するのに最適なツールのように思えます。ActionViewModel でを作成し、そのenabledIfオブザーバブルを文字列の変更の結果とし、このアクションを に接続しますUIButton。このようにして、ボタンが自動的に有効になります。

ViewModel で、これを追加する必要があります。

var buttonAction: CocoaAction {
    let hasString = self.someString.map { !$0.isEmpty }
    return CocoaAction(enabledIf: hasString) {
        // do something when button tapped
        return empty()
    }
}

ViewController を ViewModel にバインドするときは、次のようにします。

myButton.rx_action = viewModel.buttonAction
于 2015-11-30T13:26:21.797 に答える
4

toにバインドしてからmap、次の ようなものにバインドするだけでよいようです。someStringObserable<Bool>rx_enabledUIButton

someViewModel.someString
             .asObservable()
             .map { (str) -> Bool in
                 return someViewModel.isValidSomeString(text)
             }
            .bindTo(someUIButton.rx_enabled)
            .addDisposableTo(disposeBag)  

しかし、ビューモデルに次のようなものがあると、もっと簡単になると思いVariable<Bool>ます

struct ViewModel {
....
    canLogIn = Variable(false)
}

この場合、次のようにバインドできますrx_enabled

  let userNameValidation = loginTextField
     .rx_text
     .map({!$0.isEmpty})
     .shareReplay(1)

  let passwordValidation = passwordTextField
     .rx_text
     .map({!$0.isEmpty})
     .shareReplay(1)

  let loginEnabled = combineLatest(userNameValidation, passWordValidation) { (username, password) in
     return username && password
  }

  loginEnabled
     .bindTo(loginViewModel.canlogIn)
     .addDisposableTo(disposeBag)

  loginViewModel.canlogIn
         .bindTo(loginButton.rx_enabled)
         .addDisposableTo(disposeBag)
于 2015-12-20T19:40:38.320 に答える