-
Notifications
You must be signed in to change notification settings - Fork 0
View Models
View Models are used to communicate data from the server to the client and vice-versa.
Taggloo uses View Model Factories to create View Models, to encapsulate often repeated code and consolidate on practices.
Taggloo uses two types of View, conventional Views and Partial Views. Each type of View has a View Model associated with it, and therefore a View Model Factory.
View Models for Partial Views are defined as interfaces, implemented by the View Model for the containing View.
The page View Model is the IndexViewModel.
This View Model has fields related to the Index view's behaviour.
The Index view contains the _LargeTranslateForm Partial View, which uses an implementation of the ILargeTranslateFormViewModel View Model, which is implemented by the IndexViewModel.
The IndexViewModel is constructed using the IndexViewModelFactory, which itself delegates the population of fields for the ILargeTranslateFormViewModel to a further View Model Factory, LargeTranslateFormViewModelFactory.
View Model Factories must implement either the IViewModelFactory<TViewModel> or IPartialViewModelFactory<TViewModel> interface, which are used according to whether the View Model should be created or configured.
View Models are created when rendering an initial page, typically upon a GET request. This populates the default field values and populated lists. Creation of View Models is used when rendering conventional Views. The IViewModelFactory<TViewModel> interface must be implemented by any View Model Factory used to create a View Model. Implementations of IViewModelFactory<TViewModel> implicitly provide configuration of an existing View Model due to its requirement of the IPartialViewModelFactory<TViewModel> interface.
View Models are configured when populating a Partial View or when responding to a page response, eg. a PUT or a POST. The View Model is passed as a ref parameter to the configuration method to allow for type covariance when a View Model implements many interfaces used across multiple Partial Views.
Consider the following code in the HomeController, which illustrates this approach, this uses Create as a result of a GET:
public async Task<IActionResult> Index()
{
// _languageRepository is an implementation of ILanguageRepository
// this gets all languages for passing to View Model Factories
IEnumerable<Language> allLanguages = await _languageRepository.GetAllLanguagesAsync();
// Use the View Model Factory for the IndexViewModel, which itself implements the ILargeTranslateFormViewModelFactory
// because the Index view requires the LargeTranslateViewModel
// The LargeTranslateViewModel is _configured_.
IndexViewModelFactory viewModelFactory = new IndexViewModelFactory(allLanguages);
IndexViewModel viewModel = viewModelFactory.Create();
return View(viewModel);
}
This can be extended to illustrate how a postback may be handled:
[HttpPost]
public async Task<IActionResult> Index(IndexViewModel viewModel) // the incoming View Model
{
// _languageRepository is an implementation of ILanguageRepository
// this gets all languages for passing to View Model Factories
IEnumerable<Language> allLanguages = await _languageRepository.GetAllLanguagesAsync();
// Use the View Model Factory for the IndexViewModel, which itself implements the ILargeTranslateFormViewModelFactory
// because the Index view requires the LargeTranslateViewModel
// The LargeTranslateViewModel is _configured_.
IndexViewModelFactory viewModelFactory = new IndexViewModelFactory(allLanguages);
viewModelFactory.Configure(ref viewModel);
return View(viewModel);
}