ASP.NET MVC: Nesting ViewModels within each other,

2020-03-03 07:42发布

I have a project where ViewModels are nested within each other such that they essentially are a string-typed replication of the domain hierarchy. For example, if our domain has the following relationships:

Organization has 1 to many Environments

Environment has 1 to many Machines

then there will be an OrganizationViewModel that has one to many EnvironmentViewModels in it, and the EnvironmentViewModel will have one to many MachineViewModels themselves. This style of hierarchy is then reused throughout the app, with one of about five ViewModels of this type. (e.g. EnvironmentViewModel is used for multiple pages, MachineViewModel for many of them as well, depending on the level of the hierachy being viewed...I've simplified this for purposes of discussion but the hierachy is a little larger than just the 3 above).

Now, as much as I'd like to come down from above and condemn this practice, I haven't been able to find much information on this. Can anyone point me to more details about established practice? Anecdotes to share?

(My own bias is that these ViewModels shouldn't be nested within each other this way, and the ViewModels should actually correspond to the Views, not the domain objects. I find it pretty messy with some maintainability issues. But I'd like to know what others think or have experienced.)

I've attached this question for reference but it describes nesting a domain object within a viewmodel, not viewmodels within each other.

5条回答
甜甜的少女心
2楼-- · 2020-03-03 08:25

ViewModels should be associated with UI concepts, not necessarily domain concepts. So in your example I can imagine one screen that shows the organization details and a listing of Environments; clicking an Environment brings you to a details screen which then shows a listing of the Machines; and clicking one of those brings you to a Machine Details View.

In that example there are 2 different views of an Environment or Machine, the summary view that takes up a row in the listing, and the details view that takes up the better part of a screen - each of which should have it's own ViewModel. I would probably create ViewModels for this like so:

OrganizationDetailsViewModel
----List of EnvironmentSummaryViewModels


EnvironmentDetailsViewModel
----List of MachineSummaryViewModels

MachineDetailsViewModel

Depending on how complex your UI is this nesting can get deeper. Lets imagine that you had a little graphical status indicator for the environment that looked at the status and displayed in a certain color. You could create a separate EnvironmentStatusViewModel that would then be nested within the EnvironmentSummaryViewModel and possibly also nested within the EnvironmentDetailsViewModel.

查看更多
劳资没心,怎么记你
3楼-- · 2020-03-03 08:29

We've followed Josh Smith's article Simplifying the WPF TreeView by Using the ViewModel Pattern in the past. Though it is with WPF instead of MVC, I believe the concept is still applicable. I found it to be a reasonable mechanism for separating out the concerns of display in each context and allowing greater flexibility with re-use.

HTH

查看更多
Fickle 薄情
4楼-- · 2020-03-03 08:32

I would say nested view models are fine. I know viewmodels are for one particular view but it's seems a bit wasteful to not make use of my Address ViewModel by nesting it within various other view models. Certainly makes updating it a lot easier and gives a nice structure.

I do try to keep mine as flat as possible though as normally 1 level of nesting caters for most scenarios I found come across.

Related question I answered here: Two models in one view in ASP MVC 3

查看更多
够拽才男人
5楼-- · 2020-03-03 08:45

The viewmodel should be as flat as possible (although nested immutable objects used to logically group multiple related properties are ok for tidying purposes).

Dont think of it as "the viewmodel should correspond to the view", think of it the other way around: "the view is an html representation of the viewmodel data".

ViewModel is a horrible term because its not a view and its not a model, its a representation of a resource.

If I do:

`GET /User/1`

I expect back some data representing User 1. If thats in HTML format because i sent

`Accept: text/html`

then so be it. Consider what your viewmodel would look like as XML or JSON.

Try and avoid nesting viewmodels as youre creating a dependency chain, just duplicate the properties, youre not violating DRY really

查看更多
你好瞎i
6楼-- · 2020-03-03 08:47

I still want to know the advantages... and disadvantages. Is it faster - or simpler to read? If you have a view that needs to render all the info isn't it simpler to eager fetch everything to display in a single DB Get instead of multiple lazy chatty connections?

In one view wouldn't the user want to see the "organization summary" which includes all associated "Environments" and "Machines". The counts of the potentially nested items if nothing else. (Not the Environment and Machine details - these merit different views)

There seems to be a leaning towards building views to serve a single responsibility (View Machine (only shows machine info) -> View Machine Detail (only shows Machine Detail) ) It would be simple enough to make this happen but there comes a time when the views are not feature rich as there is simply too little information.

查看更多
登录 后发表回答