如何更新列表<模型与GT;使用jQuery的MVC 4 [英] How to Update List<Model> with jQuery in MVC 4

查看:81
本文介绍了如何更新列表<模型与GT;使用jQuery的MVC 4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在创建使用修改后的指数视图设置页面。我们的目标是,让用户使用一个单独的按钮的所有设置的显示,并且可以修改的所有的设置一个视图的范围内,保存的所有设置。该设置应使用Ajax进行更新。

I am currently trying to create a settings page using a modified Index view. The goal is that the users get all settings displayed and can change all settings within one view and save all settings using one single button. The setting should be updated using Ajax.

我目前的做法:

查看:

<script language="javascript">
    $(function() {
        $('#editSettings').submit(function () {
            if ($(this).valid()) {
                $.ajax({
                    url: this.action,
                    type: this.method,
                    data: $(this).serialize(),
                    success: function (result)
                    {
                        alert(result);                       
                    }
                });
            }
            return false;
        });
    });
</script>

[ ... ]

@using (Ajax.BeginForm("Edit", "Settings", new AjaxOptions {UpdateTargetId = "result"}, new { @class = "form-horizontal", @id = "editSettings" } ))
{
    foreach (Setting item in ViewBag.Settings) 
    {
        @Html.Partial("_SingleSetting", item)
    }
    <input type="submit" value="modify" />
}

部分查看加载设置:

        <div class="control-group">
            <label class="control-label">@settingName</label>
            <div class="controls">
                @Html.EditorFor(model => model.Value)
                <span class="help-inline">@settingDescription</span>
            </div>
        </div>

模型:

[Table("Settings")]
public class Setting
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int SettingId { get; set; }

    public string Name { get; set; }

    [Required(AllowEmptyStrings = true)]
    [DisplayFormat(ConvertEmptyStringToNull = false)]
    public string Value { get; set; }
}

我使用的设置ViewBag ViewBag.Settings = _db.Settings.ToList();

jQuery的解析数据如下方法:

The jQuery parses the Data to the following method:

    [HttpPost]
    public ActionResult Edit(IList<Setting> setting)
    {
        Console.WriteLine(setting.Count);
        return Content(""); // Currently for testing purposes only. Breakpoint is set to setting.Count
    }

因为设置为

计数抛出一个错误。我很不清楚如何解决这个问题。

Count throws an error because setting is null. I am quite unsure how to fix this problem.

能否有人可以给我一个提示?

Can someone can give me a hint?

<一个href=\"http://stackoverflow.com/questions/7419742/how-to-updating-ienumerablemyobject-in-mvc\">This在SO已经涵盖更新集合没有Ajax的话题。但我不会明白了吧。

This topic on SO already covers updating a Collection without Ajax. But I won't get the point.

感谢您的帮助。

推荐答案

您使用的是 Ajax.BeginForm 并与jQuery再次ajaxifying形式。这是没有必要的。但你与code,真正的问题是在你的部分输入字段的名称。你是不是尊重 命名约定 使用的默认模式粘结剂结合列表。

You are using an Ajax.BeginForm and ajaxifying the form once again with jQuery. That's not necessary. But the real problem with your code is the names of the input fields in your partial. You are not respecting the naming convention used by the default model binder for binding to lists.

让我们以一个完整的示例(移除所有的噪声,如实体框架为简单起见):

Let's take a complete example (removing all noise such as Entity Framework for simplicity):

型号:

public class Setting
{
    public int SettingId { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}

控制器:

public class SettingsController : Controller
{
    public ActionResult Index()
    {
        // No idea why you are using ViewBag instead of view model
        // but I am really sick of repeating this so will leave it just that way
        ViewBag.Settings = Enumerable.Range(1, 5).Select(x => new Setting
        {
            SettingId = x,
            Name = "setting " + x,
            Value = "value " + x
        }).ToList();
        return View();
    }

    [HttpPost]
    public ActionResult Edit(IList<Setting> setting)
    {
        // Currently for testing purposes only. Breakpoint is set to setting.Count
        return Content(setting.Count.ToString()); 
    }
}

查看(〜/查看/设置/ Index.cshtml

@using (Html.BeginForm("Edit", "Settings", FormMethod.Post, new { @class = "form-horizontal", id = "editSettings" }))
{
    foreach (Setting item in ViewBag.Settings) 
    {
        @Html.Partial("_SingleSetting", item)
    }
    <input type="submit" value="modify" />
}

@section scripts {
    <script type="text/javascript">
        $('#editSettings').submit(function () {
            if ($(this).valid()) {
                $.ajax({
                    url: this.action,
                    type: this.method,
                    data: $(this).serialize(),
                    success: function (result) {
                        alert(result);
                    }
                });
            }
            return false;
        });
    </script>
}

设置部分(〜/查看/设置/ _SingleSetting.cshtml

@model Setting
@{
    var index = Guid.NewGuid().ToString();
    ViewData.TemplateInfo.HtmlFieldPrefix = "[" + index + "]";
}

<input type="hidden" name="index" value="@index" />

<div class="control-group">
    <label class="control-label">@Html.LabelFor(x => x.Name)</label>
    <div class="controls">
        @Html.EditorFor(model => model.Value)
    </div>
</div>

注意如何分里面,有必要改变HtmlField preFIX为了使HTML辅助生成正确的名称为您输入字段和尊重的命名约定。

Notice how inside the partial it is necessary to change the HtmlFieldPrefix in order for the html helpers generate proper names for your input fields and respect the naming convention.

好了,现在让我们来削减 ViewCrap 并(即,使用视图当然机型)适当做的事情。

Alright, now let's cut the ViewCrap and do the things properly (i.e. using view models of course).

与往常一样,我们开始通过编写一个视图模型:

As always we start by writing a view model:

public class MyViewModel
{
    public IList<Setting> Settings { get; set; }
}

然后我们适应控制器:

Then we adapt the controller:

public class SettingsController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel();

        // you will probably wanna call your database here to 
        // retrieve those values, but for the purpose of my example that
        // should be fine
        model.Settings = Enumerable.Range(1, 5).Select(x => new Setting
        {
            SettingId = x,
            Name = "setting " + x,
            Value = "value " + x
        }).ToList();
        return View(model);
    }

    [HttpPost]
    public ActionResult Edit(IList<Setting> setting)
    {
        // Currently for testing purposes only. Breakpoint is set to setting.Count
        return Content(setting.Count.ToString()); 
    }
}

查看(〜/查看/设置/ Index.cshtml

@model MyViewModel

@using (Html.BeginForm("Edit", "Settings", FormMethod.Post, new { @class = "form-horizontal", id = "editSettings" }))
{
    @Html.EditorFor(x => x.Settings)
    <input type="submit" value="modify" />
}

@section scripts {
    <script type="text/javascript">
        $('#editSettings').submit(function () {
            if ($(this).valid()) {
                $.ajax({
                    url: this.action,
                    type: this.method,
                    data: $(this).serialize(),
                    success: function (result) {
                        alert(result);
                    }
                });
            }
            return false;
        });
    </script>
}

有关设置模型编辑器模板(〜/查看/设置/ EditorTemplates / Settings.cshtml

Editor template for the Settings model (~/Views/Settings/EditorTemplates/Settings.cshtml):

@model Setting
<div class="control-group">
    <label class="control-label">@Html.LabelFor(x => x.Name)</label>
    <div class="controls">
        @Html.EditorFor(model => model.Value)
    </div>
</div>

所有按照惯例,现在的作品。无需编写任何foreach循环。在 @ Html.EditorFor(X =&GT; x.Settings)在索引视图呼叫分析视图模型的设置属性,并检测到它的一些其他的集合模型(在这种情况下设置)。因此,将开始通过这个集合循环并搜索相应的编辑器模板(〜/查看/设置/ EditorTemplates / Setting.cshtml ),它会自动输出呈现的每个元素此集合。所以,你甚至不需要在视图中写任何循环。而且除了简化您的code,现在 Html.EditorFor(X =&GT; x.Value)在编辑器中的模板将产生输入字段专有名词

All works now by convention. No need to write any foreach loops. The @Html.EditorFor(x => x.Settings) call in the Index view analyzes the Settings property of the view model and detects that it is a collection of some other model (Setting in this case). So it will start looping through this collection and search for a corresponding editor template (~/Views/Settings/EditorTemplates/Setting.cshtml) which will automatically be rendered for each element of this collection. So you don't even need to be writing any loops in your view. And in addition to simplifying your code, now the Html.EditorFor(x => x.Value) in the editor template will generate proper names for the input field.

这篇关于如何更新列表&LT;模型与GT;使用jQuery的MVC 4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆