2016-10-12 3 views
0

Моей целью является изменение модели в нескольких режимах. Так как иногда мои модели имеют много свойств, я хочу изменить их в нескольких режимах. Что-то вроде:редактирование модели более чем в одном представлении

первой страница редактирует 2 свойства, вторые правки 3 других свойств, ...

модель выглядит следующим образом:

public class LoadViewModel 
{ 
    public int CurrentPage { get; set; } = -1; 
    public PageViewModel PageViewModel { get; set; } 
} 

public class PageViewModel 
{ 
    public string Param1 { get; set; } 
    public string Param2 { get; set; } 
    public int Param3 { get; set; } 
} 

мой взгляд на индексе-странице выглядит следующим образом :

@model LoadViewModel 
@using(Ajax.BeginForm("Load", "Home", new AjaxOptions {UpdateTargetId = "page"}, new {lvm = Model})) 
{ 
    <div id="page"></div> 
    <input type="submit"/> 
} 

и это мое действие:

public ActionResult Load(LoadViewModel lvm = null) 
{ 
    if (lvm == null) lvm = new LoadViewModel(); 
    lvm.CurrentPage += 1; 
    TempData["CurrentPage"] = TempData["CurrentPage"] == null ? 0 : (int)TempData["CurrentPage"] + 1; 
    if (!partialViewDict.ContainsKey((int) TempData["CurrentPage"])) 
     TempData["CurrentPage"] = 0; 
    return PartialView(partialViewDict[(int)TempData["CurrentPage"]], lvm); 
} 

страницы просто обертоны, которые сопоставляются:

private Dictionary<int, string> partialViewDict = new Dictionary<int, string> 
{ 
    {0, "Pages/_Page1"}, 
    {1, "Pages/_Page2"}, 
    {2, "Pages/_Page3"}, 
}; 

и спроектированные так:

@using WebApplication1.Controllers 
@model LoadViewModel 
@{ 
    TempData["CurrentPage"] = 0; 
} 

@Html.DisplayNameFor(m => m.PageViewModel.Param1) 
@Html.EditorFor(m => m.PageViewModel.Param1) 

это работает. При переключении на страницу 2 модель правильно установлена, но при попадании в submit значение Param1 (установленное на странице 1) сбрасывается до null, и только значения, установленные в текущей частичной части, являются правильными.

Это Страница2:

@using WebApplication1.Controllers 
@model LoadViewModel 
@{ 
    TempData["CurrentPage"] = 1; 
} 
@Html.DisplayNameFor(m => m.PageViewModel.Param2) 
@Html.EditorFor(m => m.PageViewModel.Param2) 

Когда я добавить @Html.HiddenFor(m => m.PageViewModel.Param1) в частичное, значение все еще установлен. Но я не хочу, чтобы значения были сброшены. Я не хочу добавлять @Html.HiddenFor для всех свойств, заданных в предыдущем представлении. Как я могу предотвратить сброс значений при нажатии submit без добавления @Html.HiddenFor для всех не перечисленных атрибутов? Или есть ли другая возможность поймать мою цель?

ответ

1

Для этого есть две части: первая, сама по себе и ее проверка. Для этого каждый шаг должен иметь свою собственную модель представления, содержащую только свойства, которые он должен изменить. Это позволяет вам добавить все что вам нужно, не заставляя другие шаги терпеть неудачу. В конце вы объедините данные из всех этих данных в свой класс сущности или что-то еще.

Это приводит нас ко второй части. он получает данные с каждого шага. Единственными данными, которые будут существовать после POST, являются данные, которые были опубликованы, и все, что было в сеансе (включая TempData). Вы всегда можете создать кучу скрытых полей для хранения данных с предыдущих шагов, но это может стать немного трудным. Скорее всего, вы просто захотите использовать сеанс.

TempData - это в основном специализированный экземпляр Session, поэтому вы не имеете значения.С TempData вам нужно будет запомнить вызов TempData.Keep() для каждого из ключей, которые вы установили для каждого шага, или вы потеряете предыдущие шаги в следующем запросе. Session сохранит их для жизни сеанса, но вы должны помнить, что ключи в конце должны быть удалены Session.Remove().

+0

hmm .. так что, возможно, создавая viewmodel для каждого шага, а затем позже сопоставьте их с одним, если последний шаг будет отправлен? (Я могу сохранить их только в базу данных, если был отправлен последний шаг). Если есть 2 человека, они не будут переопределять объект TempData от другого пользователя? –

+0

Совсем нет. 'Session' /' TempData' специфичен для клиента. На клиенте установлен файл cookie, который уникально идентифицирует их данные сеанса. –

+0

mhh okay, и у вас есть идея, если это может быть проблемой производительности для хранения большой viewmodel в таких TempData? (возможно, 50 объектов с большими строками). Поэтому при отправке я мог отображать модель просмотра страницы в большую модель просмотра (например, AutoMapper), которая может быть сохранена в базе данных, когда пользователь закончит все. Будет ли это хорошей процедурой? –

0

Вы используете @using (Html.BeginForm()) в своем .cshtml?

К сожалению, это MVC. MVC является апатридом, а это означает, что если вы его не сделаете, вы потеряете его :(

Если вы используете привязку к модели и строительные леса, вы можете сэкономить время и работу, но в конце это будет то же самое решение.

+0

, но должно быть любое решение для модификации модели в нескольких взглядах !? В противном случае, похоже, это действительно статично. Моя цель - создать потоки установки, в которых пользователь может инициализировать и настроить приложение (подобное окну после установки ОС) - и ему не придется прокручивать железного человека (226 км)). Нет. Я уже использую 'Ajax.BeginForm()'. с 'Html.BeginForm()' не возможно –

+0

Незначительный nit-picking, но просто хочу уточнить: HTTP-апатрид. MVC фактически не является, поскольку он поддерживает концепцию сессий, которые добавляют состояние. Однако, предполагая, что сеансы не используются, запросы будут «без гражданства». –

Смежные вопросы