Reputation: 871
I am trying to use MVVM without Rx in Objective C, basically something like MVP. I have some very basic doubts that I would like to clear
1.) How to load the initial view state in view, based on configuration. i.e. when the initial state of UI components can change based on some configuration values. For ex. A button in the view can initially be enabled/disabled/hidden based on the global configuration. How this initial view state should be rendered where there can be lots of UI components in a view?
2.) How to handle states of individual UI components?
3.) I am confused who should trigger certain operations, for instance, let's say "validation". For example in a login screen who should trigger the validation of email/password values?
Upvotes: 2
Views: 1458
Reputation: 33967
Wow, there's a lot of questions packed into this one... Let's see what I can tease out:
How this initial view state should be rendered where there can be lots of UI components in a view?
When not using a reactive system, whether in Objective-C or Swift, my view controllers end up with a configureWithViewModel:
(Obj-C) or configure(viewModel:)
(swift) function that is called in viewDidLoad
and every time the view model changes. The initial state is rendered in viewDidLoad when the configure method is called.
Should view model pass this config (or view state object) to view and view decides how to renders itself? Should View model pass the state of each UI element to the view?
The view decides how to render itself, the viewModel decides what the values should be. The viewModel only deals with the parts of the view that are dynamic. So, for example if the only thing that will be different in a UILabel is the text, then the viewModel provides a String for the text. If the UILabel also changes textColor then the viewModel provides both a String and a UIColor.
In case of Rx should VM have one view state property or state properties of each UI component?
Personally, I give the viewModel a separate Observable for each dynamic piece of view, but in a non-Rx context I feel that's too complex and will have only one update
that provides all the state at once.
How to handle states of individual UI components?
- Should VM ever ask the view to update its view state via methods like enableButton1, hideTextView etc. or
- It should just pass the "events" or data to the view and let the view decide how to react to these events.
Through data. The view isn't deciding though. For example UIButton
has an isEnabled
property. The data in this case is obviously a Bool
. The viewModel provides the Bool and the ViewController simply assigns that bool to the View (or the view assigns it to itself.)
In Rx world should view bind with individual state properties or to just event properties?
State properties. something like:
viewModel.isMyButtonEabled
.bind(to: myButton.rx.isEnabled)
I am confused who should trigger certain operations, for instance, let's say "validation". For example in a login screen who should trigger the validation of email/password values?
The wording above is a bit confusing. Nothing "triggers operations". The input portions of the view inform the view model when something has been inputed and the view model either ignores that input or updates its state. If it updates its state, then it sends the update to the output portions of the view. So for validation as an example, you can do one of two things:
When the user taps the "send" button, the view model is handed the email and password. It takes care of what to do and changes its state based on the values of those strings. Then it notifies the view controller that its state has changed.
As the user enters data in each text field, possibly even for each individual character, the view model is handed the current text field values. It takes care of what to do and changes its state based on the values of those strings. Then it notifies the view controller that its state has changed.
- Should view ask VM to validate and then ask to execute login process or
- Should view just pass the click action to VM with email/password values and VM decides whether to do validation or not and what to do if it passes or fails?
The latter. The idea is to move as much work as possible out of the view controller so that it is easier to control/test.
Upvotes: 3