Возврат списка <E>из модели представления - PullRequest
0 голосов
/ 20 июля 2011

Это моя ситуация:

У меня есть эта модель представления:

public class ViewModel
{
   public DateTime someDate { get; set; }
   public String someString { get; set; }
   public List<E> someList { get; set; }
}

Что мне нужно сделать, это установить представление даты, написать текст, а затем выбрать изсписок E любое число E. Возвращенная в действии ViewModel должна иметь дату, текст и содержать список выбранных элементов.

Что мне нужно знать, так это то, как обрабатывать указанный список.Как я могу добавить каждый выбранный элемент в список моделей.Я думал добавить свойство public bool selected в E, а затем отправить все элементы и отфильтровать выбранные на сервере, однако я бы не стал отправлять туда и обратно все эти данные, поскольку список может быть довольно большим.

Я использую MVC3 с бритвой и JQUERY AJAX для всех своих бланков.

Если я не проясняю себя, пожалуйста, дайте мне знать.

Спасибо.

1 Ответ

6 голосов
/ 20 июля 2011

Вот одна из техник, которую вы могли бы использовать для достижения этой цели.

Начнем с представления модели:

public class ViewModel
{
    public DateTime SomeDate { get; set; }
    public string SomeString { get; set; }
    public List<E> SomeList { get; set; }
}

public class E
{
    public bool Selected { get; set; }
    public string Foo { get; set; }
    public string Bar { get; set; }
}

затем мы пишем некоторый контроллер для обработки рендеринга представления и AJAX-запроса:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new ViewModel
        {
            SomeDate = DateTime.Now,
            SomeString = "some text",
            SomeList = Enumerable.Range(1, 7).Select(x => new E
            {
                Foo = "foo " + x,
                Bar = "bar " + x
            }).ToList()
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(ViewModel model)
    {
        // Here we will get our view model properly bound and 
        // the list will contain only the items that the user
        // has selected (see below...)

        // TODO: do some processing

        return Content("Thanks for submitting this data", "text/plain");
    }
}

затем мы переходим к представлению ~/Views/Home/Index.cshtml:

@model ViewModel

@using (Html.BeginForm()) 
{
    <div>
        @Html.LabelFor(x => x.SomeDate)
        @Html.EditorFor(x => x.SomeDate)
    </div>

    <div>
        @Html.LabelFor(x => x.SomeString)
        @Html.EditorFor(x => x.SomeString)
    </div>

    <table>
        <thead>
            <tr>
                <th></th>
                <th>Foo</th>
                <th>Bar</th>
            </tr>
        </thead>
        <tbody>
            @Html.EditorFor(x => x.SomeList)
        </tbody>
    </table>

    <input type="submit" value="Send selected values to server using AJAX" />
}

и, наконец, мы определяем шаблон редактора для типа E (~/Views/Home/EditorTemplates/E.cshtml), который будет отображаться для каждого элемента коллекции:

@{
    var index = Guid.NewGuid().ToString();
    var prefix = Regex.Replace(ViewData.TemplateInfo.HtmlFieldPrefix, @"\[\d+\]$", match =>
    {
        return string.Format("[{0}]", index);
    });
    ViewData.TemplateInfo.HtmlFieldPrefix = prefix;
}
<input type="hidden" name="SomeList.Index" value="@index" />
<tr>
    <td>
        @Html.DisplayFor(x => x.Foo)
        @Html.HiddenFor(x => x.Foo)
    </td>
    <td>
        @Html.DisplayFor(x => x.Bar)
        @Html.HiddenFor(x => x.Bar)
    </td>
    <td>
        @Html.CheckBoxFor(x => x.Selected)
    </td>
</tr>

ОК, поэтому на данном этапе мы еще не написали часть javascript, поэтому она должна вести себя как обычная HTML-форма, и при ее отправке все значения отправляются на сервер.

И, наконец, AJAXify формы и POST только записи, выбранные пользователем в запросе. Таким образом, мы могли бы сделать это в отдельном файле JavaScript:

$(function () {
    $('form').submit(function () {
        // we clone the original form and we will
        // filter out the non-selected fields
        var myForm = $(this).clone(false, false);

        $('tr', myForm).each(function () {
            var isSelected = $(':checkbox', this).is(':checked');
            if (!isSelected) {
                $(this).remove();
            }
        });

        $.ajax({
            url: this.action,
            type: this.method,
            data: myForm.serialize(),
            success: function (result) {
                alert(result);
            }
        });

        return false;
    });
});

В качестве хорошей статьи для обработки динамических списков я бы порекомендовал вам следующий пост в блоге .

...