MVC Razor @foreach

2020-01-24 19:57发布

I heard that having @foreach inside of a view is a no-no. Meaning, the view should not have any logic in it. What is the best practice on where the logic for the @foreach should be at?

    @foreach.. 

5条回答
2楼-- · 2020-01-24 20:17

When people say don't put logic in views, they're usually referring to business logic, not rendering logic. In my humble opinion, I think using @foreach in views is perfectly fine.

查看更多
我想做一个坏孩纸
3楼-- · 2020-01-24 20:17

I'm using @foreach when I send an entity that contains a list of entities ( for example to display 2 grids in 1 view )

For example if I'm sending as model the entity Foo that contains Foo1(List<Foo1>) and Foo2(List<Foo2>)

I can refer to the first List with:

@foreach (var item in Model.Foo.Foo1)
{
    @Html.DisplayFor(modelItem=> item.fooName)
}
查看更多
虎瘦雄心在
4楼-- · 2020-01-24 20:21

a reply to @DarinDimitrov for a case where i have used foreach in a razor view.

<li><label for="category">Category</label>
        <select id="category">
            <option value="0">All</option>
            @foreach(Category c in Model.Categories)
            {
                <option title="@c.Description" value="@c.CategoryID">@c.Name</option>
            }
        </select>
</li>
查看更多
唯我独甜
5楼-- · 2020-01-24 20:29

What is the best practice on where the logic for the @foreach should be at?

Nowhere, just get rid of it. You could use editor or display templates.

So for example:

@foreach (var item in Model.Foos)
{
    <div>@item.Bar</div>
}

could perfectly fine be replaced by a display template:

@Html.DisplayFor(x => x.Foos)

and then you will define the corresponding display template (if you don't like the default one). So you would define a reusable template ~/Views/Shared/DisplayTemplates/Foo.cshtml which will automatically be rendered by the framework for each element of the Foos collection (IEnumerable<Foo> Foos { get; set; }):

@model Foo
<div>@Model.Bar</div>

Obviously exactly the same conventions apply for editor templates which should be used in case you want to show some input fields allowing you to edit the view model in contrast to just displaying it as readonly.

查看更多
虎瘦雄心在
6楼-- · 2020-01-24 20:37

The answer will not work when using the overload to indicate the template @Html.DisplayFor(x => x.Foos, "YourTemplateName) .

Seems to be designed that way, see this case. Also the exception the framework gives (about the type not been as expected) is quite misleading and fooled me on the first try (thanks @CodeCaster)

In this case you have to use @foreach

@foreach (var item in Model.Foos)
{
    @Html.DisplayFor(x => item, "FooTemplate")
}
查看更多
登录 后发表回答