2010-08-05 12 views
31

I am amorevole MVC 2. Il tutto si adatta perfettamente al web.Come posso utilizzare Html.DisplayFor all'interno di un iteratore?

C'è un pezzo di funzionalità, tuttavia, che non sono in grado di convincere dalla funzione Html.DisplayFor():

<@ Page Inherits="ViewPage<IEnumerable<Foo>>"> 

<% foreach(var item in Model) { %> 

    <%: Html.DisplayFor(item.BarBaz) %> 

<% } %> 

ho bisogno di essere in grado di utilizzare il DisplayTemplate per questo valore. C'è un modo per fare questo?

risposta

63

In realtà, l'ho capito. Che stupido da parte mia.

Questo funziona:

<@ Page Inherits="ViewPage<IEnumerable<Foo>>"> 

<% foreach(var item in Model) { %> 

    <%: Html.DisplayFor(m => item.BarBaz) %> 

<% } %> 
+2

Penso, sono ancora più stupido, perché non sono sicuro di come interpretarlo. Il parametro formale lambda m non viene utilizzato nell'espressione. Quindi è presente solo perché è richiesto da _DisplayFor_? Inoltre, mi aspettavo che '@Html.Display (item.BarBaz)' funzionasse altrettanto bene, ma questo non rende nulla. –

+0

@ R.Schreurs Sembra che lambda debba essere un'espressione 'Func' che prende come parametro il tipo del modello, ma può restituire qualsiasi cosa. – JohnnyHK

+0

Anch'io sono stupido :) –

10

si può realizzare che da allontanarsi dal foreach e utilizzando un normale ciclo for:

<% for (int i = 0; i < Model.Count(); i++) { %> 

    <%: Html.DisplayFor(p=> p.ElementAt(i).BarBaz) %> 

<%} %> 

Un'altra opzione sarebbe quella di creare un PartialView che ha preso un oggetto Foo e visualizzate solo le informazioni che si voleva.

<% foreach (var item in Model) 
    { 
     Html.RenderPartial("FooBarBazLine", item); 
    } %> 
+1

mi piace l'opzione 2 meglio – Necros

+1

+1, ma sto con Necros/opzione 2 è molto più pulito – Tahbaza

+1

Sono d'accordo che l'opzione 2 sia una soluzione migliore. Ho appena incluso l'opzione 1 come pensavo prima e non avevo davvero alcun motivo per rimuoverlo poiché risolve il problema. – sgriffinusa

3

Html.DisplayFor può iterare automaticamente collezioni, mostrando una visione parziale per ogni elemento della collezione.

La prima cosa che devi fare è creare una classe modello attuale, con la collezione come proprietà della classe.

public class Bar 
{ 
    public IEnumerable<Foo> foo { get; set; } 
} 

Restituisce questa classe dal controller anziché dalla raccolta non elaborata.

In secondo luogo è necessario un modello di visualizzazione per la classe Foo. I modelli di visualizzazione sono viste parziali che devono essere collocati nella cartella Views/Shared/DisplayTemplates.

Modifica: è possibile averli anche nella sottocartella controller di Views se si desidera limitare il modello a un controller specifico. Vedere this question per ulteriori informazioni.

Ecco un esempio nella sintassi rasoio:

@model YourNameSpace.Foo 
<p>@Model.BarBaz</p> 

Salva come Foo.cshtml nella DisplayTemplates cartella di cui sopra.

Questo modello è piuttosto semplice perché si basa sul tuo esempio in cui si sta visualizzando solo una stringa, ma se gli elementi della raccolta in cui una classe con le proprie proprietà è possibile creare un modello più elaborato.

Ora nella vista originale, si può sbarazzarsi del ciclo del tutto e solo scrivere

@Html.DisplayFor(m => m.foo) 

Avviso foo è il nome della proprietà nella nuova classe del modello che contiene la vecchia collezione si Looped finita prima .

DisplayFor saprà automaticamente che la proprietà foo è di tipo (raccolta di) Foo e ritirare il modello Foo.cshtml nella cartella DisplayTemplates e dimostrare una volta per ogni elemento in foo.

+0

Immagina di avere un sacco di modelli, con liste come questa ** IEnumerable **. Hai intenzione di creare un modello per mille-entità? Tutto ciò di cui hai bisogno è solo un modello generico per i tipi di base, come stringa, intero, booleano, ecc. – Alexander

+0

Non hai davvero bisogno di bar, nel caso in cui la collezione foo sia accessibile, per esempio, staticamente? O è solo una variabile locale? – toddmo

6

Questa è una vecchia questione, ma credo che qualcuno possa ottenere benefici da mia soluzione:

vista aspx

<%@ Page Inherits="ViewPage<IEnumerable<Foo>>" %> 

<% foreach (var item in Model) { %> 

    <%: Html.DisplayFor(m => item) %> 

<% } %> 

vista Razor

@model IEnumerable<Foo> 

@foreach (var item in Model) 
{ 
    Html.DisplayFor(m => item) 
} 

Dal DisplayFor accetta un lambda tipizzato implicito, possiamo indicare direttamente l'istanc e da visualizzare nel loop.

Infine, io sono d'accordo con la risposta Anders E. Andersen s' per l'utilizzo del modello

0

In Razor sto usando

@Html.DisplayFor(model => item.CreatedDate) 
Problemi correlati