ASP.NET MVC 3 Custom Display Template With UIHint - For Loop Required?
Asked Answered
W

3

8

If i have a ViewModel like this:

public class MyViewModel
{
   [UIHint("SomeTemplate")]
   public ICollection<SomeViewModel> Submodel { get; set; }
}

And a strongly-typed View with a line of HTML like this:

@Html.DisplayFor(model => model.Submodel)

And a display template with a signature like this:

@model MvcApplication1.Models.SomeViewModel

I get an error saying "the model item is of type List<SomeViewModel> but this dictionary requires a model of type SomeViewModel.".

Which makes sense, but i would have hoped the built-in templating smarts of MVC would kick in, see it's a IEnumerable of something and work out to call my template N amount of times, like how it usually does for Html.DisplayFor without the hint.

So it looks like [UIHint] overrides that functionality?

Obviously i can point to another template which accepts the collection, and calls Html.DisplayForModel(), basically emulating MVC smarts. But i am hoping to avoid that. Honestly i would rather do a foreach loop than having that 1 line "wrapper" template.

Any better ideas?

It's like i want to say: "Hey MVC, render out a template for each one of these guys. But instead of using name-convention to find the template, here's a hint".

Welcome answered 23/5, 2011 at 6:47 Comment(0)
M
7

UIHint means "Render this model using the template named XXX". So you have to declare your displaytemplate "SomeTemplate" with

@model MvcApplication1.Models.ICollection<SomeViewModel>

And display each item inside a foreach.

Manipur answered 23/5, 2011 at 6:53 Comment(7)
so there's no way to leverage mvc's built in templating smarts (implicit loop) whilst still using uihint?Welcome
Nope, not in my knowledge. Even if you wanted to implement it, what should be rendered to surround all the elements ? In some cases it should be a table, in other cases an ul/ol.Manipur
the thing is, i already have a display template for SomeViewModel, but the reason i am using UIHint is because i want to override this default template with the new one. Default templating for a collection will simply render out the individual template N times. It doesn't make decisions on ul/table. I simply want to render out a different template N times. but looks like it cant be done without a for loop, which kinda sucks. I always try to avoid loops.Welcome
Ok, I see. Looks like my comment applied on MVC2, where you had to use UIHint for collections.Manipur
Nps. I'll leave this question open for a bit to see if there is a better solution, otherwise i'll accept this one.Welcome
This behavior is not nice of MVC3. The implicit loop should really work with UIHint. Is there a way to write custom logic (without having to rebuild the whole MVC)?Angeles
I usually handle this type of template with two templates. One that is the loop, and that loop references the template for individual items. I actually have never heard of implicit looping, and googling for MVC implicit looping doesn't turn up anything. Maybe you are thinking of how it by default loops through each metadata property and displays the object template or UIHint template as necessary. This is not looping over a collection, but actually going through properties. Maybe you can enlighten me as to what you are talking about.Expose
E
3

An alternative is to pass the string template name as follow

@Html.DisplayFor(model => model.Submodel, "SomeTemplate")
Eipper answered 7/6, 2013 at 14:23 Comment(1)
Yea this nice to keep things tidy. Maybe an example will help people started.Bottrop
A
2

I ran into the same problem. It looks like UIHint is ignored by default for complex types. You can override the behavior but it is not straightforward. So the simpler solution would be:

1) Remove the UIHint annotation. 2) Instead make sure your display template file is named as the type name you want the Html.DisplayFor to automatically iterate over. So in your case, name the display template file as SomeViewModel.cshtml. This should work. There is no need to explicitly use the for loop. I have tried it in MVC4 and it works.

I got the solution from the following link: http://roysvork.wordpress.com/2012/12/09/dynamic-repeating-field-groups-in-asp-net-mvc-with-just-a-dash-of-knockout-js/

Analeptic answered 5/6, 2013 at 22:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.