Closed sedwo closed 6 years ago
Hi @sedwo.
This is a normal behaviour.
In the second example (the one where the row stays empty), before binding the model with the row, the value of self._textRow.rx.value
is nil
. So when the first binding is setup, this nil
value propagated to the self.model.text
(which was "RxEureka" before). Then, the second binding just throws back the nil
value of model's text property to the TextRow value.
In order to avoid this :
Use whatever order you want, but after binding just change the value of your model property. ex :
self._textRow.rx.value
.asObservable()
.bind(to: self.model.text)
.disposed(by: self._disposeBag)
self.model.text
.asObservable()
.bind(to: self._textRow.rx.value)
.disposed(by: self._disposeBag)
self.model.text.value = "YOLO"
I see. But the init()
method already executed setting the string value.
Is there a way to force the binding to refresh itself, allowing the already set value to propagate again? (without setting a new value, again)
I noticed in your example that you use .bind(to:
as well as .subscribe(
for the same variables. Which I've followed as a template but now wonder if .bind(to:
is really necessary when the following still works?
private func configureBindingsWithViewModel() {
// Bind viewModel Variable to--> 'email' row
// self.viewModel.usernameText
// .asObservable()
// .bind(to: self.emailRow!.rx.value)
// .disposed(by: self.disposeBag)
// Update UI row value when data changes within viewModel.
self.viewModel.usernameText
.asObservable()
.subscribe(onNext: { value in
self.emailRow?.value = value
self.emailRow?.updateCell() // refresh UI control
}, onError: { error in
DDLogError("RxError = \(error)")
}, onDisposed: {
DDLogError("onDisposed")
}).disposed(by: self.disposeBag)
The reason for .subscribe(
being necessary is that Eureka won't refresh the UI row for you. You must call .updateCell()
. Is it safe to remove the .bind(to:
step then, as it doesn't seem to make any difference here.
If you just need to synchronise your values between your Eureka
row and your RxSwift
Variable in your viewModel, just use the 2 ways binding pattern.
In your exemple this could be :
self.viewModel.usernameText
.asObservable()
.bind(to: self.emailRow.rx.value)
.disposed(by: self.disposeBag)
self.emailRow.rx.value
.asObservable()
.bind(to: self.viewModel.usernameText)
.disposed(by: self.disposeBag)
In the project sample I subscribe to the viewModel's variables just to have a log feedback of the user interaction within the Eureka
rows.
RxEureka
update the cell for you, so you don't have to subscribe to your viewModel changes and refresh manually the corresponding row.
I hope i have been clear enough.
Got it. Thank you.
It's not clear to me why this happens.
When you init:
within
private func _configureBindings() {
when the order of binding sets up theVariable
first and then therow
:The form field correctly displays the default value:
But when you swap the order, by binding the
row
first and then theVariable
:The form field is missing its default value: