在MVC4中,如何一次保存多行编辑?

9

我找到的所有MVC4应用程序示例都只支持逐行编辑。它会显示所有数据行,每一行都有一个编辑按钮,点击后跳转到另一个页面以便编辑该行数据。

我希望能够将所有数据元素按行显示,并且不用让用户为每一行点击编辑按钮,而是所有行的数据点已经在文本框中,用户可以直接更新。页面上只有一个保存按钮,可以一次性保存所有更新/编辑的内容。

我该如何设置我的MVC应用程序来支持这种操作?


你是在寻找使用PostBack还是Ajax模型来发送更新吗? - Heather
我想现在我会寻找最简单的...因为我正在学习MVC4。假设那将是postback。但我可以使用任何模型。谢谢 - dan27
2个回答

12

你可以使用EditorTemplates来实现此功能。以下示例展示了普通表单提交示例。如果需要,您可以使用serialize方法将表单值发送并通过ajax进行处理。

假设您需要编辑某门课程的学生姓名列表。那么让我们为此创建一些视图模型。

public class Course
{
  public int ID { set;get;}
  public string CourseName { set;get;}
  public List<Student> Students { set;get;}

  public Course()
  {
    Students=new List<Student>();
  }
}
public class Student
{
  public int ID { set;get;}
  public string FirstName { set;get;}
}

现在在你的GET操作方法中,你需要创建一个我们的视图模型的对象,初始化Students集合并将其发送到我们的强类型视图。

public ActionResult StudentList()
{
   Course courseVM=new Course();
   courseVM.CourseName="Some course from your DB here";

   //Hard coded for demo. You may replace this with DB data.
   courseVM.Students.Add(new Student { ID=1, FirstName="Jon" });
   courseVM.Students.Add(new Student { ID=2, FirstName="Scott" });
   return View(courseVM);
}

现在,在Views/YourControllerName下创建一个名为EditorTemplates的文件夹。然后在其中创建一个名为Student.cshtml的新视图,其内容如下:

@model Student
@{
    Layout = null;
}
<tr> 
 <td>
  @Html.HiddenFor(x => x.ID)
  @Html.TextBoxFor(x => x.FirstName ) </td>
</tr>

现在在我们的主视图(StudentList.cshtml)中,使用EditorTemplate HTML助手方法来调用这个视图。

@model Course
<h2>@Model.CourseName</h2>
@using(Html.BeginForm())
{
  <table>
     @Html.EditorFor(x=>x.Students)
  </table>
  <input type="submit" id="btnSave" />
}

这将在一个表行中,将所有UI与每个学生的姓名放入文本框中。现在,当表单提交时,MVC模型绑定将在我们的视图模型的Students属性中具有所有文本框的值。

[HttpPost]
public ActionResult StudentList(Course model)
{
   //check for model.Students collection for each student name.
   //Save and redirect. (PRG pattern)
}

Ajax化的解决方案

如果你想使这个页面Ajax化,你可以监听提交按钮的点击事件,获取表单并序列化它,并将其发送到相同的后端处理方法。在保存操作完成后,不要重定向页面,而是返回一个指示该操作状态的JSON。

$(function(){
  $("#btnSave").click(function(e){
    e.preventDefault();  //prevent default form submit behaviour
    $.post("@Url.Action("StudentList",YourcontrollerName")",
                    $(this).closest("form").serialize(),function(response){
   //do something with the response from the action method
    });
  });
});

好的,这个很好用。问题是:如果你上面的学生类有一个GenderId元素,并且它是指向一个Gender类的外键,该类具有int GenderId、string GenderName。我想在表单中显示/编辑GenderName,以使其更加用户友好,但更新genderid。我可以让gendername显示出来,但每当我更新它时,它就会返回null。我需要嵌套EditorTemplates吗? - dan27
@dan27:记住这些是专门为视图设计的ViewModel类,而不是领域模型类。因此,您无需创建另一个类来保存性别信息。保持简单,将性别名称和ID放在同一个学生类中即可。 - Shyju

1

您只需要指定正确的模型、示例列表,并发送带有每行信息(数组元素)的ajax请求,在服务器端读取它并相应地更新每个元素。为此,您可以使用Post请求。只需将元素列表作为参数传递到控制器中,并使用ajax传递它。

例如,您的控制器可以定义为:

public ActionResult Update(List<MyEntity> list)
{
...
}
public class MyEntity
{
public string Name {get; set;}
public int Count {get; set;}
}

而JavaScript可以是:

var myList = new Array();
// fill the list up or do something with it.

$.ajax(
{
   url: "/Update/",
   type: "POST",
   data: {list: myList}
}
);

当然,您的“保存”按钮会有单击事件处理程序,将使用ajax调用该功能。
为了方便起见,您可以考虑使用KnockoutJS或其他MVVM框架,在客户端将数据与DOM绑定。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接