2013-06-19 7 views

Antwort

5

Verwenden Sie eine For-Schleife statt für jede und übergeben Sie den Indexer in die EditorFor Erweiterung; Rasierer sollte den Rest behandeln.

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

Update:

Pass in dem Index des Elements oben mit Blick Daten zeigen.

In Ihrem Editor Vorlage Zugriff der Artikel über die ViewBag

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

gut, aber wie kann ich das "i" in der EditorTemplate? – Andrei

+0

Wenn Sie '@ Html.EditorFor' in der EditorTemplate verwenden, müssen Sie den Index des Elements nicht kennen, Razor wird die Elemente entsprechend benennen, damit sie wieder in eine Sammlung posten können. Wenn Sie den Index jedoch auf andere Weise verwenden möchten, können Sie ihn in ViewData übergeben. Siehe Bearbeitungen. – Jay

+0

Das wird funktionieren! :) Ich frage mich nur, dass der Index da ist. Razor weiß es. Wie kann man es bekommen? – Andrei

2

Sie @ Html.NameFor verwenden können (m => m.AnyField). Dieser Ausdruck gibt die vollständige Namenseigenschaft einschließlich des Index aus. Sie könnten den Index dort extrahieren ...

+0

, die gültig ist, aber es gibt eine bessere Option, um es direkt zu extrahieren. Siehe meine Antwort unten. – iberodev

4

Verwenden der EditorTemplate ist die beste Lösung beim Anzeigen von Modellen, die eine Liste von etwas enthalten.

Um den Index für das Untermodell zu finden gerenderten Sie die Eigenschaft verwenden können, die Razor von Standardsätze:

ViewData.TemplateInfo.HtmlFieldPrefix 

Nehmen wir zum Beispiel haben Sie die folgende Ansicht Modelle:

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

und

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

    public string Text {get; set;} 
} 

und Sie wollen in der Lage sein, alle die „LineVM“ innerhalb eines bearbeiten "AbsatzVM". Dann würden Sie eine Editor-Vorlage verwenden, so dass Sie einen Blick auf den folgenden Ordner erstellen würden (wenn es nicht existiert) mit den gleichen Namen als Untermodell 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> 

Vorausgesetzt, dass Sie einen Kontrolleurs haben Action, dass eine Ansicht und Leiten eines ParagrapghVM Viewmodel auf eine Ansicht, zum Beispiel wiederkehr Views/Paragraph/_Paragraph.cshtml:

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

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

Diese Ansicht als viele Editoren für die Liste Linien als Elemente machen würde enthält diese Liste. Also, wenn zum Beispiel die Eigenschaftsliste ParagraphVM.Lines 3 Elemente enthält, würde es so etwas wie machen:

<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> 

Damit Sie wissen genau, welche Position die jeweils ein Element innerhalb der Liste ist und zum Beispiel einige Javascript verwenden, um Erstelle ein Karussell oder was auch immer du damit machen willst. Aber denken Sie daran, dass Sie diese Position nicht wirklich kennen müssen, da Razor sich darum kümmert. Wenn Sie das Modell ParagraphVM zurücksenden, werden die Werte in der Liste Lines (falls vorhanden) ohne zusätzliche Arbeit gebunden.

4

Wie wäre:

@using System 
@using System.Text.RegularExpressions 

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

Ich habe diese HtmlExtension benutze, die nur die benötigten id einer Iteration zurückgibt. Es ist im Grunde eine Regex auf ViewData.TemplateInfo.HtmlFieldPrefix, die die letzte Nummer erfasst.

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; 
    } 
} 

Kann in einer EditorFor-Vorlage wie folgt verwendet werden:

@Html.Index() 
0

ich die einfachste Art und Weise denken ist:

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

Oder als Helfer:

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

Inspiriert von @Jona und @Ryan Penfold

Verwandte Themen