Выберите элементы из списка <T> в MVC 4, используя привязку модели

Дали класс

public class Person
{
    // Some general properties

    public List<Hobby> Hobbies { get; set; }
}

public class Hobby
{
    // Some properties e.g. Name, etc.
}

static List<Hobby> AllHobbies { get; }

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

Конечно, было бы возможно в циклеAllHobbies и сделать<input type="checkbox" /> для каждого, затем свяжите выбранные значения вручную в контроллере обратной передачи. Кажется, что это должно быть выполнимо с привязкой модели, но я не вижу как.

Ответы на вопрос(1)

Решение Вопроса

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

public class Hobby
{
    public string Name { get; set; }
    public bool Selected { get; set; }
}

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

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var person = new Person
        {
            Hobbies = new[]
            {
                new Hobby { Name = "hobby 1" },
                new Hobby { Name = "hobby 2", Selected = true },
                new Hobby { Name = "hobby 3" },
            }.ToList()
        };
        return View(person);
    }

    [HttpPost]
    public ActionResult Index(Person person)
    {
        var selectedHobbies = person
            .Hobbies
            .Where(x => x.Selected).Select(x => x.Name);
        string message = string.Join(",", selectedHobbies);
        return Content("Thank you for selecting: " + message);
    }
}

затем представление, содержащее форму, позволяющую пользователю выбирать хобби:

@model Person

@using (Html.BeginForm()) 
{
    <h2>Hobbies</h2>
    @Html.EditorFor(x => x.Hobbies)
    <button type="submit">OK</button>
}

и соответствующий шаблон редактора, который будет автоматически отображаться для каждого элементаHobbies коллекция (~/Views/Home/EditorTemplates/Hobby.cshtml - & GT; обратите внимание, что имя и местоположение шаблона имеет важное значение):

@model Hobby

<div>
    @Html.LabelFor(x => x.Selected, Model.Name)
    @Html.HiddenFor(x => x.Name)
    @Html.CheckBoxFor(x => x.Selected)
</div>

Для более сложных сценариев редактирования я бы рекомендовал вам пройтись по Стивену Сандерсону.Сообщение блога по теме.

 Eric J.11 июн. 2012 г., 21:06
Можете ли вы порекомендовать шаблон для эффективного (как во времени, потраченного на кодирование и тестирование) отображения между моделью предметной области и моделью представления? На самом деле это первый случай (хотя я очень мало занимаюсь разработкой пользовательского интерфейса), где между ними было какое-то различие.
 11 июн. 2012 г., 21:03
Нет, ваша ошибка в том, что вы передаете модель домена на ваш взгляд. Это не верно. Вы должны определить модель представления. Внутри этой модели у вас будет логическое значениеSelected свойство, которое позволит вам работать с флажками внутри представления и извлекать выбранные значения пользователем. Затем вы сопоставите результат с моделью вашего домена, чтобы сделать с ней все, что вам нужно. Помните самое важное правило в MVC: действия контроллера передают / принимают только модели представления в / из представлений. Не доменные модели. Модели представлений - это классы, которые вы специально разрабатываете для удовлетворения требований данного представления.
 11 июн. 2012 г., 21:08
Лично я использую AutoMapper:automapper.org
 12 июн. 2012 г., 01:05
Нет, вывод модели представления непосредственно из модели предметной области - очень плохая идея. Не делай этого.
 Eric J.11 июн. 2012 г., 20:58
+1, отличная информация.Hobby Однако класс не имеет (и не должен) иметь логическое значение, указывающее, выбрал ли его конкретный пользователь с точки зрения модели предметной области (это, конечно, упрощенный пример). Должен ли я добавить временное логическое поле к объекту, чтобы поддержать это, или есть другой способ сделать привязку без этого дополнительного поля?

Ваш ответ на вопрос