web-dev-qa-db-fra.com

MVC Razor @foreach

J'ai entendu dire qu'avoir @foreach à l'intérieur d'une vue est un non-non. Cela signifie que la vue ne doit pas contenir de logique. Quelle est la meilleure pratique pour savoir où devrait se situer la logique de @foreach?

    @foreach.. 
72
Nate Pet

Quelle est la meilleure pratique pour savoir où devrait se situer la logique de @foreach?

Nulle part, juste s'en débarrasser. Vous pouvez utiliser l'éditeur ou des modèles d'affichage.

Donc par exemple:

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

pourrait parfaitement être remplacé par un modèle d'affichage:

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

et ensuite vous définirez le modèle d'affichage correspondant (si vous n'aimez pas le celui par défaut ). Donc, vous définiriez un modèle réutilisable ~/Views/Shared/DisplayTemplates/Foo.cshtml qui sera automatiquement rendu par le framework pour chaque élément de la collection Foos (IEnumerable<Foo> Foos { get; set; }):

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

Bien entendu, les mêmes conventions s'appliquent aux modèles d'éditeur à utiliser si vous souhaitez afficher certains champs de saisie vous permettant d'éditer le modèle de vue par opposition à un affichage en lecture seule.

148
Darin Dimitrov

Lorsque les gens disent de ne pas mettre de logique dans les vues, ils font généralement référence à la logique métier, et non à la logique de rendu. À mon humble avis, je pense que l’utilisation de @foreach dans les vues convient parfaitement.

88
JonoW

J'utilise @foreach lorsque j'envoie une entité contenant une liste d'entités (par exemple, pour afficher 2 grilles dans une vue)

Par exemple, si j'envoie comme modèle l'entité Foo qui contient Foo1(List<Foo1>) et Foo2(List<Foo2>)

Je peux me référer à la première liste avec:

@foreach (var item in Model.Foo.Foo1)
{
    @Html.DisplayFor(modelItem=> item.fooName)
}
12
Mihai Labo

une réponse à @DarinDimitrov pour un cas où j'ai utilisé foreach dans une vue rasoir.

<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>
9
Nicholas King

La réponse ne fonctionnera pas si vous utilisez la surcharge pour indiquer le modèle @Html.DisplayFor(x => x.Foos, "YourTemplateName).

Semble être conçu de cette façon, voir ce cas . De plus, l'exception fournie par le framework (à propos du type non conforme aux attentes) est assez trompeuse et m'a trompée du premier coup (merci @CodeCaster)

Dans ce cas vous devez utiliser @foreach

@foreach (var item in Model.Foos)
{
    @Html.DisplayFor(x => item, "FooTemplate")
}
2
Tiberiu Craciun