2011-01-27 22 views
6

Ho una pagina mvc con un displaytemplate. Come ottengo l'indice dell'elemento corrente da sottoporre a rendering in displaytemplate. produce risultati associabili corretti negli attributi del nome.Indice dell'articolo corrente nel modello di visualizzazione mvc

<input name="xxx[0].FirstName"/> 
<input name="xxx[1].FirstName"/> 

Desidero che il valore dell'indice nel modello di visualizzazione. È in ViewContext da qualche parte?

@ * @ page.cshtml @model ... @ proprietà Contatti è IEnumerable * @

<table id="contacts" class="editable"> 
    <thead> 
    <tr><th>Name</th><th>Surname</th><th>Contact Details</th></tr> 
    </thead> 

    <tbody> 
    @Html.DisplayFor(x => x.Contacts) 
    </tbody> 

nel modello di visualizzazione che abbiamo

@* contact.cshtml *@ 
@model [email protected]* This is the T of the IEnumerable<T> *@ 

<tr> 
    @* I NEED THE INDEX OF THE CURRENT ITERATION HERE *@ 
    <td>@Html.DisplayFor(x => x.FirstName)</td> 
</tr> 

risposta

12

temo ci sia nessun modo semplice per ottenere l'indice. È sepolto all'interno del metodo interno System.Web.Mvc.Html.DefaultDisplayTemplates.CollectionTemplate e non esposto. Che cosa si potrebbe utilizzare è il prefisso campo:

@ViewData.TemplateInfo.HtmlFieldPrefix 

Un'altra possibilità è sostituire @Html.DisplayFor(x => x.Contacts) con:

@for (int i = 0; i < Model.Contacts.Length; i++) 
{ 
    @Html.DisplayFor(x => x.Contacts[i], new { Index = i }) 
} 

e poi all'interno del template @ViewBag.Index dovrebbe darvi l'indice corrente, ma devo ammettere che è un po brutto.

+0

Grazie, io analizzarlo fuori del prefisso. – Jim

+2

@Jim, fai attenzione con il parsing perché potresti avere livelli profondi come 'Contacts [5] .Addresses [7]'. –

+0

Grazie per il suggerimento, lo terrò a mente. Dieci anni fa avrei trascorso alcune settimane a scrivere il parser multi livello più flessibile ed elegante. Oggi prenderò l'ultimo numero corrispondente e ci arriverò! – Jim

0

A seconda del motivo per cui è necessario l'indice, potrebbe esserci un modo più semplice.

che stavo facendo qualcosa di simile e volevo l'indice solo così ho potuto facilmente numerare l'elenco di elementi quali:

  1. Primi elementi in lista
  2. secondo elemento in lista ecc

La soluzione forse ovvia era il rendering del mio modello di visualizzazione come elemento di elenco all'interno di un elenco ordini e lasciare che il browser gestisse la visualizzazione dell'indice. Inizialmente lo facevo in una tabella e avevo bisogno dell'indice da visualizzare nella tabella, ma l'utilizzo di una lista ordinata lo rende molto più semplice.

Quindi la mia vista padre aveva la seguente:

<ol> 
    @Html.DisplayFor(m => m.Items) 
</ol> 

E il mio modello scritto il gli elementi in un elemento di elenco utilizzando div - nota si potrebbe usare div galleggianti, o meglio ancora display: inline-style per ottenere una tabella come effetto

<li> 
    <div class="class1">@Html.DisplayFor(m => m.ItemType)</div> 
    ... 
</li> 

E il css:

.class1 { 
    display: inline-block; 
    width: 150px; 
} 
2

estensione @ DarinDimitrov di risposta, ho voluto presentare una soluzione completa:

Estensione:

namespace ApplicationName.Helpers 
{ 
    public static class RazorHtmlHelpers 
    { 
     public static Int32 GetTemplateIndex(this TemplateInfo template) 
     { 
      var index = 0; 

      var match = Regex.Match(template.HtmlFieldPrefix, @"\d"); 
      Int32.TryParse(match.Value, out index); 

      return index; 
     } 
    } 
} 
Parent

Vista Markup:

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

Markup Template:

@using ApplicationName.Helpers 
@model ApplicationName.Models.ModelName 

<span>Item @ViewData.TemplateInfo.GetTemplateIndex()</span> 
Problemi correlati