Visualizações parciais MVC (ou modelos de editor):anexar índice ao nome de entrada para uso múltiplo do formulário?

StackOverflow https://stackoverflow.com/questions/6328582

Pergunta

Como posso adicionar um índice para inserir nomes e IDs em formulários que são usados ​​várias vezes em uma visualização?

Eu criei um formulário para o rotador de fotos que oferece a capacidade de editar uma legenda específica do contexto para cada foto (outdoor).Preciso ser capaz de incluir várias instâncias dos campos do formulário para isso, para que os administradores possam editar todas as legendas do conjunto de fotos de um rotador em uma visualização e, portanto, preciso de uma maneira de manter os IDs e os nomes dos campos exclusivos.

Os modelos do editor adicionam automaticamente um prefixo, mas quando faço um loop nas fotos assim:

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

Simplesmente adiciona "billboard_" como prefixo, o que não resolve meu problema.

Eu gostaria de anexar o ID do rotador ID do outdoor ao final de cada nome e ID de entrada:

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

Alguma maneira fácil de fazer isso?

Foi útil?

Solução

por favor baixe isso código de amostra de Steve Sanderson postagem no blog.não está diretamente relacionado à sua pergunta.Mas no projeto de demonstração você encontrará o auxiliar html BeginCollectionItem que está alterando o escopo do prefixo para entrada ou série de entradas.Isso pode lhe dar um ponto de partida
Editar:
em seu modelo de editor, você pode usar o seguinte método do código de Steve, como

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

se o ID for propriedade do seu modelo e tiver valor, por exemplo, 4, você terá html como

<label>Image</label>
<input name = "BillBoard4.Image" .../>
<label>Caption</label>
<input name = "BillBoard4.Caption" .../>

Outras dicas

Observação:Os recursos usados ​​abaixo podem não existir há 4 anos...Em primeiro lugar, você não precisa mais usar o Beestings, a sintaxe @ usada nos exemplos de barbear é muito mais limpa.

O método que você está chamando está em System.Web.Mvc.Html.EditorExtensions:

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

Sua abordagem:

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

O corpo da expressão x => billboard é um ConstantExpression.

Essa abordagem resulta na aplicação do escopo apropriado no EditorTemplate:

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

Se Model.BillBoards é uma matriz, a expressão x => Model.BillBoards[i] pode ser descrito como

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

Se Model.BillBoards é um IList<T>, a expressão x => Model.BillBoards[i] pode ser descrito como

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

As sobrecargas de EditorFor() que aceitam Expressões verificam o Type e o NodeType do corpo da expressão e constroem o escopo de acordo.

Este código deve ser equivalente se você não tiver mais nada dentro do loop:

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

Se você tiver apenas uma visualização somente leitura e uma visualização de edição, poderá renomear seus modelos e remover o segundo parâmetro.Supondo BillBoard é sua classe Model, renomeie BillboardForm.cshtml para EditorTemplates/BillBoard.cshtml, e altere o código para

@Html.EditorFor(x => Model.BillBoards)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top