Navigation and MVVM

One of the key purposes of the MVVM pattern is to isolate an app's presentation layer from its other layers; in doing so, an app's business logic is also isolated. One of the thoughts behind this isolation is to have a user interface that is only concerned with displaying data and that is completely independent of how that data is stored, acquired, manipulated, or shared with the rest of the app. As explained in Chapter 2, MVVM and DataBinding, this is typically accomplished through databinding. In MVVM, the actions that a user takes on a page are bound to commands on that page's backing ViewModel. It is very common for actions to result in a transition to another page—either by directly linking to it or by automatically navigating to a previous page after performing a task, such as saving data. Because of this, it makes sense to rethink how we do navigation in an app that leverages the MVVM pattern so that it can be controlled by ViewModels and not by the pages.

Most common third-party MVVM frameworks and toolkits subscribe to this theory and often even provide a navigation service that is designed for ViewModel consumption.

There are a couple of approaches to consider when performing navigation within ViewModels. One approach is page-centric and the other is ViewModel-centric. A page-centric approach involves navigating to another page by a direct reference to that page. A ViewModel-centric approach involves navigating to another page by reference to that page's ViewModel.

The page-centric approach can be accomplished in Xamarin.Forms by simply passing the current Xamarin.Forms.INavigation instance into a ViewModel's constructor. From there, the ViewModel can use the Xamarin.Forms default navigation mechanism to navigate to other pages. The benefits of this approach are that it separates the navigation functionality from the page layer, and it's fairly quick to implement. However, the downside is that is puts a strong dependency on direct page references into ViewModels. I typically prefer to use the ViewModel-centric approach and keep ViewModels loosely coupled and agnostic of the actual page implementations.

ViewModel-centric navigation

As previously discussed, the ViewModel-centric approach alleviates a ViewModel of having any dependencies on the specific implementation of individual pages. In a default Xamarin.Forms solution, this might not appear to be such a big deal, but imagine if pages were self-contained in their own library—the library containing ViewModels probably wouldn't have a reference to that library. This is typical of a traditional Xamarin-based cross-platform solution architecture, and a good practice to follow.

Because ViewModel doesn't navigate directly to a page, it will navigate to a page via the page's ViewModel. This means that when implementing this approach, there is a need to build a relationship, or mapping, between pages and their ViewModels. As with most things in software, this can be done in a couple of ways. One way is to include a dictionary or key-value type property in the navigation service that maintains a one-to-one mapping of pages and ViewModels using their Type. This could also be done external of the navigation service to provide additional abstraction. Another approach that is employed by the MVVM Light (http://mvvmlight.codeplex.com/) toolkit's navigation service is to map the Type of ViewModel with a String key that represents the actual pages.

In the next section, we'll create a ViewModel-centric navigation service that includes ViewModel and page Type mapping.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.255.178