Получить подмножество ViewModel из RenderPartial на POST - PullRequest
2 голосов
/ 24 февраля 2012

У меня есть ViewModel, которая содержит дочернюю ViewModel.В строго типизированном Viewed родительского объекта я хочу сделать RenderPartial для дочернего элемента, и результаты сохраняются после POST.Но дочерние поля всегда нулевые.

Это должно сработать, не так ли?Я довольно новичок в MVC, надеюсь, мне не хватает чего-то простого.Надеюсь, кто-то может указать на это!

Спасибо!

Пример

ViewModels

public class EggBoxViewModel
{
    public string Brand { get; set; }
    public int Price { get; set; }
    public EggViewModel Egg { get; set; }
}

public class EggViewModel
{
    public string Size { get; set; }
    public bool IsBroken { get; set; }
}

Контроллер

public ActionResult Demo()
{
    EggBoxViewModel eggBox = new EggBoxViewModel();
    eggBox.Brand = "HappyEggs";
    eggBox.Price = 3;

    EggViewModel egg = new EggViewModel();
    egg.Size = "Large";
    egg.IsBroken = false;

    eggBox.Egg = egg;

    return View(eggBox);
}

[HttpPost]
public ActionResult Demo(EggBoxViewModel eggBox)
{

    // here, eggBox.Egg is null
}

Просмотров "Демо"

@model MvcApplication1.ViewModels.EggBoxViewModel

@using (Html.BeginForm())
{
    <h2>EggBox:</h2>
    <p>
    @Html.LabelFor(model => model.Brand)
    @Html.EditorFor(model => model.Brand)
    </p>
    <p>
    @Html.LabelFor(model => model.Price)
    @Html.EditorFor(model => model.Price)
    </p>

    <p>
        @{Html.RenderPartial("_Egg", Model.Egg);}
    </p>

    <input type="submit" value="Submit" />
}

"_ Яйцо" (Частичное)

@model MvcApplication1.ViewModels.EggViewModel

<h2>Egg</h2>
<p>
@Html.LabelFor(model => model.Size)
@Html.EditorFor(model => model.Size)
</p>
<p>
@Html.LabelFor(model => model.IsBroken)
@Html.CheckBoxFor(model => model.IsBroken)
</p>

Ответы [ 2 ]

2 голосов
/ 25 июля 2012

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

@model MvcApplication1.ViewModels.EggViewModel

<h2>Egg</h2>
<p>
@Html.LabelFor(model => model.Size)
@Html.EditorFor(model => model.Size)
</p>
<p>
@Html.LabelFor(model => model.IsBroken)
@Html.CheckBoxFor(model => model.IsBroken)
</p>

Затем в вашем демонстрационном представлении используйте новый шаблон редактора вместо частичного:

<p>
    @Html.EditorFor(x => x.Egg)
</p>

Здесь - это поля, которые отображаются:

Rendered fields

В сообщении вы можете сказать, что EggViewModel теперь является частью EggBoxViewModel:

Также в ModelState вы можете видеть, что поля Egg имеют префикс имени свойства, используемого в EggBoxViewModel, что делает их подмножеством EggBox.

И ... замечательно, что если вы хотите иметь коллекцию Eggs в своем EggBox, это действительно просто ... просто сделайте свое свойство Egg в EggBoxViewModel коллекцией:

public class EggBoxViewModel
{
    public string Brand { get; set; }
    public int Price { get; set; }
    public ICollection<EggViewModel> Eggs { get; set; }
}

Добавьте второе яйцо:

public ActionResult Demo()
{
    EggBoxViewModel eggBox = new EggBoxViewModel();
    eggBox.Brand = "HappyEggs";
    eggBox.Price = 3;

    EggViewModel egg = new EggViewModel();
    egg.Size = "Large";
    egg.IsBroken = false;

    EggViewModel egg2 = new EggViewModel();
    egg2.Size = "Medium";
    egg2.IsBroken = false;

    eggBox.Eggs = new List<EggViewModel>();

    eggBox.Eggs.Add(egg);
    eggBox.Eggs.Add(egg2); 

    return View(eggBox);
}

Измените ваше представление для отображения x.Eggs вместо x.Egg:

<p>
    @Html.EditorFor(x => x.Eggs)
</p>

Затем в ответном сообщении вы увидите, что отправлено 2 яйца:

enter image description here

Имена полей были автоматически проиндексированы и названы для создания коллекции яиц:

enter image description here

0 голосов
/ 24 февраля 2012

вам придется изменить модель частичного представления на EggBoxViewModel, чтобы объект Egg был виден на виде.то есть:

@model MvcApplication1.ViewModels.EggBoxViewModel
<h2>
    Egg</h2>
<p>
    @Html.LabelFor(model => model.Egg.Size)
    @Html.EditorFor(model => model.Egg.Size)
</p>
<p>
    @Html.LabelFor(model => model.Egg.IsBroken)
    @Html.CheckBoxFor(model => model.Egg.IsBroken)
</p>

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

@{Html.RenderPartial("_Egg", Model);}

теперь вы должны увидеть объект Egg в вашей модели, возвращаемый в HttpPost действие.

The object debug

[метод обновления 2]

хорошо, очень быстро редактировать !!Вы можете сохранить все так же, как изначально, и попробовать это в своей части (я не уверен на 100%, что это будет работать, хотя):

@model MvcApplication1.ViewModels.EggViewModel
<h2>
    Egg</h2>
<p>
    @Html.LabelFor(model => model.Size)
    @Html.Editor("Egg.Size", Model.Size)
</p>
<p>
    @Html.LabelFor(model => model.IsBroken)
    @Html.CheckBox("Egg.IsBroken", Model.IsBroken)
</p>

здесь, я просто использую @Html.Editor() и введите требуемыйназвание модели, а не @Html.EditorFor().Хорошо, gorra dash ... тренируйся в 'кеш'; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...