Использование одного частичного просмотра несколько раз в одном родительском представлении - PullRequest
6 голосов
/ 27 июня 2011

Я использую бритву MVC3.У меня есть сценарий, в котором я должен использовать частичное представление несколько раз в одном родительском представлении.Проблема, с которой я сталкиваюсь, заключается в том, что при отображении родительского представления оно генерирует те же имена и идентификаторы элементов управления вводом в этих частичных представлениях.Так как мои частичные представления связаны с разными моделями, при повторном просмотре представления «Сохранить» происходит сбой.Любая идея, как я могу сделать идентификатор элемента управления / имена уникальными, возможно, некоторые, как их префикс?

В ожидании

Набиль

Ответы [ 2 ]

6 голосов
/ 27 июня 2011

Лично я предпочитаю использовать шаблоны редакторов, так как они позаботятся об этом.Например, у вас может быть следующая модель представления:

public class MyViewModel
{
    public ChildViewModel Child1 { get; set; }
    public ChildViewModel Child2 { get; set; }
}

public class ChildViewModel
{
    public string Foo { get; set; }
}

и следующий контроллер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            Child1 = new ChildViewModel(),
            Child2 = new ChildViewModel(),
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

и в представлении Index.cshtml:

@model MyViewModel
@using (Html.BeginForm())
{
    <h3>Child1</h3>
    @Html.EditorFor(x => x.Child1)

    <h3>Child2</h3>
    @Html.EditorFor(x => x.Child2)
    <input type="submit" value="OK" />
}

и последняя часть - шаблон редактора (~/Views/Home/EditorTemplates/ChildViewModel.cshtml):

@model ChildViewModel

@Html.LabelFor(x => x.Foo)
@Html.EditorFor(x => x.Foo)

Используя EditorFor, вы можете включить шаблон для различных свойств модели основного вида, и будут сгенерированы правильные имена / идентификаторы.В дополнение к этому вы получите правильное заполнение модели представления в действии POST.

2 голосов
/ 18 июня 2013

Существует альтернатива:

  1. Добавить префикс к PartialView
  2. Привязать модель, удалив префикс

Для 1 установитепрефикс в вашем представлении:

ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "prefix";

Для 2 вы можете восстановить данные с помощью UpdateModel, например:

UpdateModel(producto, "prefix");

Это не очень рекомендуется, поскольку ваши действия неполучить данные в качестве параметра, но позже обновит модель.Это имеет несколько неудобств: 1) непонятно, что нужно вашему действию, глядя на его сигнатуру 2) нелегко предоставить входные данные для действия для его модульного тестирования 3) действие уязвимо для параметров переполнения (параметров, предоставленных пользователемэто не должно быть там и сопоставлено с моделью).

Однако, для 2 есть альтернатива: зарегистрируйте пользовательское связующее устройство модели, которое позволяет вам удалить префикс.И пользовательский связыватель моделей должен знать об этом.

Хорошее решение в этом вопросе и ответах: Как обрабатывать префикс привязки модели MVC с одинаковой формой, повторяемой для каждой строки коллекции? Ноу него есть небольшой недостаток: если вы добавляете скрытое поле с именем «__prefix» в частичном представлении и визуализируете его несколько раз как частичное представление, этот идентификатор будет повторяться для нескольких различных элементов на странице, что не являетсяразрешено, и может вызвать некоторые проблемы.И одной из наиболее важных причин предоставления префикса является точная рендеринг того же представления «редактирования», что и частичных представлений для нескольких экземпляров объекта.То есть это может произойти на такой странице, как gmail, где вы можете редактировать несколько писем одновременно.

Существует несколько возможных решений этой проблемы.

Одним из них является предоставление префикса в качестве запроса.значение строки или Routedata, а не как поле формы, которое позволяет избежать конфликтов Id и может быть найдено механизмом связывания модели.(У него всегда может быть одно и то же имя).

Другое решение заключается в использовании скрытого поля с фиксированным рисунком, но различного для каждого визуализированного представления.Префикс может следовать этому шаблону для уникальности: «PP $ ActionControllerId», как «PP $ EditProduct23», который уникален для каждого отображаемого представления и может быть легко найден между параметрами запроса, ища тот, который начинается с «PP $».

И окончательным решением будет создание префикса только в представлении, а не предоставление его в каком-либо параметре запроса.Связыватель модели должен будет искать префикс, исследующий имена параметров запроса, пока не найдет тот, чей префикс следует шаблону.

Конечно, настраиваемый ModelBinder должен быть адаптирован для работы с выбранным соглашением.

...