I've see various examples where the form is built in the VC, some parts in the VM, and bound with Rx.
But is there a proper "elegent" technique to employ using this form engine?
How _do you_ integrate the Eureka forms engine properly into the MVVM architecture?
We did not design Eureka with MVVM in mind but we have used it in MVVM.
We had a ViewModel
with one variable for each value in the form (i.e. one for each row).
final class RegisterViewModel {
private(set) open var formValues: Variable<[String : Any?]>
private(set) var firstLastName: String = ""
private(set) var dateOfBirth: Date = Date()
// plus some helper functions and vars
}
We created the form in the View
part of the architecture, more specifically in the ViewController. Then we populated the rows with the values from the ViewModel
.
<<< TextRow(RegisterViewModel.RowTags.firstLast) {
$0.value = viewModel.firstLastName
$0.title = "Name"
$0.add(rule: RuleMinLength(minLength: viewModel.nameMinLength))
}
<<< DateInlineRow(RegisterViewModel.RowTags.dateOfBirth) {
$0.value = viewModel.dateOfBirth
$0.title = "Date of birth"
}
We had an Rx
observable to watch the values in the ViewModel
which was used to update the form when the ViewModel changed.
viewModel.formValues.asObservable()
.subscribe(onNext: { [weak self] formValues in
self?.updateForm(with: formValues)
})
.addDisposableTo(disposeBag)
Finally on submit of the form we'd call a function with the new values of the form.
self?.viewModel.submit(values: self!.form.values())
I hope this brief description can help you setting up your forms. I omitted parts of the code but I think you will find your way.
My setup is very similar, except could you elaborate how exactly you work with the formValues
variable?
As I've had binding issues that don't update the form UI automatically and am forced to row.reload()
within .onChange
.
The ViewModel
subscribes to the changes in the Model and updates its variables (firstLastName
, dateOfBirth
) and its formValues
accordingly.
As shown above the ViewController subscribes to the formValues
and calls updateForm(with: formValues)
.
This method then calls:
form.setValues(values)
tableView?.reloadData()
There might be a better way than reloading the whole table.
Does that work for you?
Most helpful comment
We did not design Eureka with MVVM in mind but we have used it in MVVM.
We had a
ViewModel
with one variable for each value in the form (i.e. one for each row).We created the form in the
View
part of the architecture, more specifically in the ViewController. Then we populated the rows with the values from theViewModel
.We had an
Rx
observable to watch the values in theViewModel
which was used to update the form when the ViewModel changed.Finally on submit of the form we'd call a function with the new values of the form.
I hope this brief description can help you setting up your forms. I omitted parts of the code but I think you will find your way.