Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
397 views
in Technique[技术] by (71.8m points)

jquery - Return a List<E> from a view in view model

This is my situation:

I have this view model:

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

What I have to do is in the view set the date, write some text and then select from a list of E any number of E. The ViewModel returned in the action must have the date, the text and contain the list of selected items.

What I need to know is how to handle said list. How can I add each selected item to the models' List. I was thinking on adding a property public bool selected to E and then send all items and filter the selected ones on the server, however I would rather not send back and forth all that data since the list can be quite large.

I am using MVC3 with razor and JQUERY AJAX for all my form posts.

If I am not making myself clear, please let me know.

Thank you.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here's one technique that you could use to achieve this.

Let's start with the view model:

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; }
}

then we write some controller to handle the rendering of the view and the AJAX request:

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");
    }
}

then we move on to the ~/Views/Home/Index.cshtml view:

@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" />
}

and finally we define an Editor template for the E type (~/Views/Home/EditorTemplates/E.cshtml) which will be rendered for each element of the collection:

@{
    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>

OK, so at this stage we haven't yet written the javascript part so this should behave as a normal HTML form and when it is submitted it will send all the values to the server.

And final piece would be to AJAXify the form and POST only the records that the user selected in the request. So we could do this in a separate javascript file:

$(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;
    });
});

As a good article for handling dynamic lists I would recommend you the following blog post.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...