Частичные представления MVC (или шаблоны редактора): добавить индекс к имени для многократного использования формы? - PullRequest
1 голос
/ 13 июня 2011

Как добавить индекс для ввода имен и идентификаторов в формах, которые используются несколько раз в одном представлении?

Я создал форму для ротатора фотографий, которая позволяет редактировать контекстную подпись для каждой фотографии (рекламный щит). Мне нужно иметь возможность включать несколько экземпляров полей формы для этого, чтобы администраторы могли редактировать все подписи для набора фотографий ротатора в одном представлении, и поэтому мне нужен способ сохранить идентификаторы и имена полей уникальными.

Редактор шаблонов автоматически добавляет префикс, но когда я зацикливаюсь на фотографиях, вот так:

<% foreach (var billboard in Model.Billboards ) {  %>
    <%: Html.EditorFor(x => billboard, "BillboardForm")%>
<% } %>

Он просто добавляет "billboard_" в качестве префикса, что не решает мою проблему.

Я хотел бы добавить идентификатор ротатора идентификатор билборда в конце каждого имени и идентификатора:

<form action="/Rotators/Edit/5" method="post">                  
    <input id="billboard_21_RotatorId" name="billboard_21_RotatorId" type="hidden" value="5" /> 
    <input id="billboard_21_ImageId" name="billboard_21_ImageId" type="hidden" value="19" />
    <label for="billboard_21_Title">Title</label>
    <textarea cols="20" id="billboard_21_Title" name="billboard_21_Title" rows="2">Title</textarea>
    <label for="billboard_21_Caption">Caption</label>
    <textarea cols="20" id="billboard_21_Caption" name="billboard_21_Caption" rows="2">This is the caption</textarea>
    <select id="billboard_21_TopicId" name="billboard_21_TopicId">
        <option value="1">1st option</option>                   
    </select>
</form>

Любой простой способ сделать это ??

Ответы [ 2 ]

1 голос
/ 13 июня 2011

Пожалуйста, скачайте код sampel из сообщения Стива Сандерсона .это не имеет прямого отношения к вашему вопросу.Но в демонстрационном проекте вы найдете помощник BeginCollectionItem html, который меняет область префикса для ввода или серии входов.Это может дать вам начальную точку
Edit:
в шаблоне вашего редактора. Вы можете использовать следующий метод из кода Стива, например

using(Html.BeginHtmlFieldPrefixScope("BillBoard" + Model.ID.ToString())){
<label>Image<label>
@Html.TextBoxFor(x=>x.Image)
<label>Caption</label>
@Html.TextBoxFor(x=>x.Caption)
}

, если ID является свойством вашей моделиимеет значение, например, 4, то у вас будет HTML как

<label>Image</label>
<input name = "BillBoard4.Image" .../>
<label>Caption</label>
<input name = "BillBoard4.Caption" .../>
0 голосов
/ 09 декабря 2015

Примечание. Используемые ниже функции могут отсутствовать 4 года назад ... Во-первых, вам больше не нужно использовать beestings, используется синтаксис @ в Razor примеры гораздо чище.

Метод, который вы вызываете, находится в System.Web.Mvc.Html.EditorExtensions:

public static MvcHtmlString EditorFor<TModel, TValue>(
    this HtmlHelper<TModel> html,
    Expression<Func<TModel, TValue>> expression
)
...

Ваш подход:

@foreach (var billboard in Model.Billboards ) {
   @Html.EditorFor(x => billboard, "BillboardForm")
}

Тело выражения x => billboard представляет собой ConstantExpression.

При таком подходе соответствующая область применения применяется в шаблоне EditorTemplate:

@for (var i = 0; i < Model.BillBoards.Count(); i++)
{
    @Html.EditorFor(x => Model.BillBoards[i], "BillboardForm")
}

Если Model.BillBoards является массивом, выражение x => Model.BillBoards[i] можно описать как

SimpleBinaryExpression{NodeType:ArrayIndex}(
    Left: ConstantExpression,
    Right: ConstantExpression
)

Если Model.BillBoards является IList<T>, выражение x => Model.BillBoards[i] можно описать как

InstanceMethodCallExpressionN(
    Method:RuntimeMethodInfo(IList<T>.get_Item (Int32 index)),
    Object:PropertyExpression(ConstantExpression),
    Arguments:[ConstantExpression]
)

Перегрузки EditorFor(), которые принимают выражения, проверяют тип тела выражения и NodeType и соответственно создают область действия.

Этот код должен быть эквивалентен, если внутри цикла больше ничего нет:

@Html.EditorFor(x => Model.BillBoards, "BillboardForm")

Если у вас есть только вид только для чтения и вид редактирования, вы можете переименовать ваши шаблоны и удалить второй параметр. Предполагая, что BillBoard является вашим классом Model, переименуйте BillboardForm.cshtml в EditorTemplates/BillBoard.cshtml, затем измените код на

@Html.EditorFor(x => Model.BillBoards)
...