I currently am wondering how to do bidirectional binding in RxSwift...
Imagine haven a ViewModel which has Variable properties. These are being set inside the ViewModel.
Now you have an interface representing these Variables and you bind the textfields with rx_text and bindTo to the ViewModel properties. How to bind the changes of the textfields to the viewmodel then?
Two way binding are just two unidirectional bindings :).
I guess you can create your function or operator to do that if you like
func twoWayBind(variable, controlProperty) -> Disposable {
let d1 = variable.bindTo(controlProperty)
let d2 = controlProperty.subscribeNext { variable.value = $0 }
return CompositeDisposable(d1, d2)
}
... something like this.
ok sounds interesting, but does not work. I try to investigate...
The problem is my Textfield is set to "" (empty string), while variable holds a value of some non-empty string
ok I came up with this
extension Variable {
public func twoWayBind<O: protocol<ObserverType,ObservableType> where O.E == E>(observer: O) -> RxSwift.Disposable {
let d1 = self.bindTo(observer)
let d2 = observer
.skip(1) //because the first is an empty and I don't know why 'til now
.subscribeNext { next in
self.value = next
}
return CompositeDisposable(d1, d2) }
}
@Fab1n Just replace order of subscription and you shouldn't need .skip(1) :)
Oh, wait, that should work without skip(1), hm ...
Ok... Tell me when you know more. It does not work until now
Hi @Fab1n ,
I've made a branch where I've tested your code
https://github.com/ReactiveX/RxSwift/commit/5dbe5719a27818f63ca6d4e4e7f7b8746c1c370d#diff-f25909400c8fc57e75fd7bf2f266695cR82
and as far as I can tell it works.
You can try it out for yourself by going to first example in RxExample app.
There was for some reason additional skip(1) in your code which I don't think it's needed. Let me know do you still have any issues with this :)
Not sure if this is still an issue, but we've added an example how this can be easily done in RxSwift here.
Closing this one for now :)
Hi,
Is there a way to bind an optional variable to a control property (for example a Variable < String? > to UITextField.rx_text)? I don't wan't my form to have default value for the first time.
Thanks for your advice.
For those of you looking for the example it's here as of 2.0.0-beta.4
@thanegill, not sure, how to use it. Can you help me?
Anyway , .skip(1) is actually needed to avoid propagating back initial value. The act of two-way binding itself causes variable update otherwise, what I presume is not considered to happen.
@ndry better than skip(1) to add check to subscribe making sure value has changed before updating value.
What, for example, happens when later on some code updates the variable?
extension Variable {
public func twoWayBind<O: protocol<ObserverType,ObservableType> where O.E == E>(observer: O) -> RxSwift.Disposable {
let d1 = self.bindTo(observer)
let d2 = observer
.subscribeNext { next in
if self.value != next {
self.value = next
}
}
return CompositeDisposable(d1, d2) }
}
@hmlongco try this
https://github.com/RxSwiftCommunity/RxBiBinding
Hey @Davarg - It's preferable to not comment on old (2-3 year old) issues with library publications :) Appreciate it, and thanks for your work!
Most helpful comment
For those of you looking for the example it's here as of 2.0.0-beta.4