This is the 3rd revision in attempt to create a more functional ViewModel. If you want to see my previous posts, please look at.
- Functional ViewModels In Xamarin.Forms (Revision 2)
- More Functional ViewModels In Xamarin.Forms With C#
Here is the revised setup:
Your XAML page already holds the visual state, there should be no reason that your ViewModel should hold this as well. Hence with this approach we send a snapshot.
With any command, we send a snapshot of the required elements in the XAML, through to the command. This has benefits of:
- No Two-Way Binding, which could mean minor performance improvements
- Snapshot of View’s state, at the time the user wants an action taken. Which I could say means a more predictable interaction as far as the user is concerned.
You will also notice I created a new markup extension called e:Pull. This is to receive the state updates from the ViewModel, without binding to a property.
I decided that the XAML would be ok, to be a little bigger than usual, if it was clear, exactly what it was doing. If you want some shorter XAML, you can go back to Revision 2, and see my attempt there.
The ViewModel is now really simple.
- Its now more functional because it isn’t holding any state
- There are no properties
- You use the Push method to push the new updates to the View.
With this approach, the state of your app would still be kept within the Model. You would inject the Model into your ViewModel, and could call methods or receive events from it, as you would normally. The View’s state would be held purely in the XAML page, and the ViewModel is now just a functional, stateless class.
Sample code available in my GitHub Repo Functional.
To answer a few questions as per my last post:
- Why not RxUI – It still duplicates state between View and ViewModel, and doesn’t provide a snapshot at the exact point of action. Rx is mainly there to handle event streams and it still uses 2 way bindings. Rx would still be good for handling event streams from the Model.
- Why not Redux – The need for Actions and a constantly created new app state, seems over the top.