2013-06-19 14 views

risposta

5

Utilizzare un ciclo for invece di ciascuno e passare l'indicizzatore nell'estensione EditorFor; il rasoio dovrebbe gestire il resto.

@for(var i = 0; i < Model.count(); i++) 
{ 
    @Html.EditorFor(m => Model.ToArray()[i], new { index = i }) 
} 

Aggiornamento:

palla nell'area della indice dell'elemento utilizzando i dati immagine come esposizione qui sopra.

Nel vostro editor di accesso modello l'articolo via il ViewBag

<span> Item Index: @ViewBag.index </span> 
+0

bene, ma come posso conoscere "i" all'interno di EditorTemplate? – Andrei

+0

Se si utilizza '@ Html.EditorFor' in EditorTemplate non è necessario conoscere l'indice dell'elemento, Razor assegnerà un nome agli elementi in modo appropriato in modo che possano postare nuovamente in una raccolta. Se tuttavia si desidera utilizzare l'indice in un altro modo, è possibile passarlo nel ViewData. Vedi le modifiche. – Jay

+0

Funzionerà! :) L'unica cosa che mi chiedo, che l'indice è lì. Il rasoio lo sa. Come si può uscirne? – Andrei

2

È possibile utilizzare @ Html.NameFor (m => m.AnyField). Quell'espressione produrrà la proprietà del nome completo incluso l'indice. È possibile estrarre l'indice lì ...

+0

valido, ma esiste un'opzione migliore per estrarlo direttamente. Vedi la mia risposta qui sotto. – iberodev

4

Utilizzare EditorTemplate è la soluzione migliore quando si visualizzano modelli che contengono un elenco di qualcosa.

Al fine di trovare l'indice per il sub-modello in fase di rendering è possibile utilizzare la proprietà che Razor imposta di default:

ViewData.TemplateInfo.HtmlFieldPrefix 

dire, per esempio, sono disponibili le seguenti modelli di visualizzazione:

public class ParagraphVM 
{ 
    public int ParagraphId { get; set; } 
    public List<LineVM> Lines { get; set; } 
} 

e

public class LineVM 
{ 
    public int Id { get; set; } 

    public string Text {get; set;} 
} 

e si vuole essere in grado di modificare tutti i "LineVM" all'interno di un "ParagraphVM". Poi si sarebbe utilizzare un Editor modello modo si creerebbe una vista alla seguente cartella (se non esiste) con lo stesso nome come il sotto-modello Views/Shared/EditorTemplates/LineVM.cshtml:

@model MyProject.Web.MVC.ViewModels.Paragraphs.LineVM 
@{ 
    //this will give you the List's element like Lines[index_number] 
    var field = ViewData.TemplateInfo.HtmlFieldPrefix; 
} 
<div id="@field"> 
    @Html.EditorFor(l => l.Text) 
</div> 

Supponendo di avere un controller di ActionResult che sta tornando una visualizzazione e il superamento di un ViewModel ParagrapghVM ad una vista, ad esempio Views/Paragraph/_Paragraph.cshtml:

@model MyProject.Web.MVC.ViewModels.Paragraphs.ParagraphVM 

@using (Html.BeginForm("Details", "Paragraphs", FormMethod.Post)) 
{ 
    @Html.EditorFor(p => p.Lines) 
} 

Questo punto di vista potrebbe rendere come molti editori per le Linee elenco come elementi contiene tale elenco. Quindi se, per esempio, i ParagraphVM.Lines elenco delle proprietà contiene 3 articoli che renderebbe qualcosa di simile:

<div id="#Lines[0]"> 
    <input id="Lines_0__Text name="Lines[0].Text"/> 
</div> 
<div id="#Lines[1]"> 
    <input id="Lines_1__Text name="Lines[1].Text"/> 
</div> 
<div id="#Lines[2]"> 
    <input id="Lines_2__Text name="Lines[2].Text"/> 
</div> 

Con questo si può sapere esattamente quale posizione Ogni gli articoli all'interno della lista e per esempio utilizzare alcuni javascript per crea una giostra o qualunque cosa tu voglia fare con essa. Ma ricorda che per modificare quella lista non hai davvero bisogno di conoscere la posizione in cui Razor si prende cura di te per te. Se si esegue il postback del modello ParagraphVM, l'elenco Lines avrà i valori associati (se presenti) senza alcun lavoro aggiuntivo.

4

ne dite:

@using System 
@using System.Text.RegularExpressions 

var i = Convert.ToInt32(Regex.Matches(
      ViewData.TemplateInfo.HtmlFieldPrefix, 
      @"\[([0-9]+)?\]")[0].Groups[1].ToString()); 
7

ho usato questo HtmlExtension che restituisce solo l'id necessaria di un'iterazione. È fondamentalmente una regex su ViewData.TemplateInfo.HtmlFieldPrefix che sta catturando l'ultimo numero.

public static class HtmlExtensions 
    public static MvcHtmlString Index(this HtmlHelper html) 
    { 
     var prefix = html.ViewData.TemplateInfo.HtmlFieldPrefix; 
     var m = Regex.Match(prefix, @".+\[(\d+)\]"); 
     if (m.Success && m.Groups.Count == 2) 
      return MvcHtmlString.Create(m.Groups[1].Value); 
     return null; 
    } 
} 

Può essere utilizzato in un EditorFor-template in questo modo:

@Html.Index() 
0

Penso che il modo più semplice è:

@Regex.Match(ViewData.TemplateInfo.HtmlFieldPrefix, @"(?!\[)\d+(?=\])") 

O come aiutante:

public static string Index(this HtmlHelper html) 
    { 
     Match m = Regex.Match(html.ViewData.TemplateInfo.HtmlFieldPrefix, @"(?!\[)\d+(?=\])"); 
     return m.Success ? m.Value : null; 
    } 

Ispirato da @Jona e @Ryan Penfold

Problemi correlati