65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 JQuery 插入、更新和删除 MVC WebGrid 数据

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.71/5 (8投票s)

2015年2月13日

CPOL

10分钟阅读

viewsIcon

150559

downloadIcon

7052

如何使用 JQuery 插入、更新和删除 MVC WebGrid 数据

引言

如果您是 ASP.NET 开发人员,您应该熟悉使用 Item Template 和 Edit Template 来编辑(插入、更新和删除)GridView 的行数据。您可能会感到惊讶,因为 MVC 的 WebGrid 没有 Edit Template,也不允许用户编辑 WebGrid 的行数据。

使用 JQuery,您可以允许用户编辑 WebGrid 中的数据。在本主题中,我将引导您完成:

  • 如何填充 WebGrid 中的数据
  • 使用 JQuery 编辑 WebGrid 中的数据

请注意,我专注于功能实现,而不是美观。在本演示中,我将使用 Student 对象来表示 student 信息。

1.0 创建 MVC 4 Web 应用程序

使用 Visual Studio 2012,创建一个新的 MVC 4 Web 应用程序项目。选择 Internet 或 Intranet 应用程序模板。我选择了 Internet Application Template。确保在 View Engine 中选择了 Razor。

默认情况下,Visual Studio 会为 Controllers、Models 和 Views 创建多个文件。在本教程中,您将修改应用程序的登录页面。换句话说,您将使用 Index.cshtml 视图来显示 Student 数据。

2.0 向项目中添加 JQuery 脚本

打开 Views->Shared 文件夹下的 _Layout.cshtml,并在 Head 的结束标签 (</head>) 前面添加以下 JQuery 引用。

        <script src="~/Scripts/jquery-1.8.2.min.js"></script>
        <script src="~/Scripts/jquery-ui-1.8.24.min.js"></script>

3.0 创建数据模型 (Student)

在 Solution Explorer 中,右键单击 Models,然后从上下文菜单中选择 Add 选项。接着选择 Class 选项,并将其命名为 Student。现在,Models 文件夹应该包含 Student.cs 类。

打开 Student.cs 并添加如下所示的字段。您可以添加验证和其他属性。为了专注于编辑功能,请保持简单。

namespace DrillDownDemo.Models
{
    public class Student
    {
        public int ID { get; set; }
        public String Name { get; set; }
        public String email { get; set; }    
    }
}

4.0 为 WebGrid 添加样式表

在本演示中,您将为 WebGrid 的交替行和页脚使用不同的背景颜色。为了实现这一点,您将使用 CSS 文件。右键单击 Content 文件夹,然后从 Add 上下文菜单中选择 New Item。在 Add New Item 对话框中选择 Style Sheet。将其命名为 Student,然后单击 Add 按钮。

打开 Student.css 文件,并将以下 CSS 语句添加到 Student.css 文件中。

.oddRowStyle
{
    background-color: #00CCFF;
    color: #FFFFFF;
}
.evenRowStyle
{
    background-color: #CCCCCC;
}
.tfootrow
{
    background-color: #3366CC;
    color: #FFFFFF;
}
    .tfootrow a
    {
        color:#FFFFFF;
    }

保存 Student.css 文件后,将 CSS 链接添加到 _Layout.cshtml 中,以便所有页面都可以使用样式表。将以下行添加到 _Layout.cshtml 文件的 HEAD 标签内。

<link href="~/Content/Student.css" rel="stylesheet" />

5.0 修改 Controller (HomeController)

对于此演示应用程序,由于您使用的是登录页面,因此需要修改 HomeController。在实际应用程序中,您可能需要在不同的视图中显示数据。在这种情况下,您将需要添加/修改相应的 controller。

为了简单起见,使用 static 数据,而不是后端数据存储。在 HomeController 中添加一个 static Student 对象列表。

public static List<Models.Student> Students = new List<Models.Student>()
            {
                new Models.Student { 
                    ID = 1, 
                    Name = "Adam Worth", 
                    email = "adam.worthh@abc.edu", 
                },
                new Models.Student { 
                    ID = 2, 
                    Name = "John Doe",  
                    email = "john.doe@abc.edu", 
                },
                new Models.Student { 
                    ID = 3, 
                    Name = "Gorge Klene", 
                    email = "gorge.klene@abc.edu", 
                }
            };

为了将 Students 列表发送到 Index 视图,请修改 Index() 方法并将 Students 返回到视图。代码行如下:

public ActionResult Index()
        {
            return View(Students);
        }

6.0 修改 View (index.cshtml)

6.1 使用 WebGrid 显示数据

打开 Views->Home 文件夹下的 Index.cshtml 文件。您需要为该视图指定数据模型。在 Index.cshtml 文件的第一行,添加以下内容:

@model IEnumerable<ManipulateWebGridDemo.Models.Student>

这会将与 System.Web.Mvc.ViewDataDictionary 关联的 Model 属性更新为 student 对象列表。Model 属性将在 WebGrid 构造函数中用作参数。

如果您愿意,可以添加 ViewBag.Title,如下所示:

@{
    ViewBag.Title = "Manipulate WebGrid Data";
} 

现在,您需要添加 WebGrid 的代码。定义一个 ID 为 <div>,并在 WebGrid 控件的 ajaxUpdateContainerId 属性中引用该 divid,这将允许 WebGrid 使用 Ajax 异步更新数据。由于数据中只有 3 条 Student 记录,如果您想查看 WebGrid 在不同页面上的行为,请将 rowsPerPage 设置为 2。

<div id="ajaxgrid">
@{
        var grid = new WebGrid(Model, ajaxUpdateContainerId: "ajaxgrid", 
                               rowsPerPage: 2);
}
</div>

接下来,您需要定义列。在第一列中,定义不同的操作(编辑、保存、取消和删除)。视图有两种不同的模式——一种用于显示,另一种用于编辑。因此,您会看到 Edit 和 Delete 操作具有 "display" 类属性,而 Save 和 Cancel 操作具有 "edit" 类属性。这些类将用于 JQuery 来确定活动模式。

要捕获用户对操作按钮的单击事件,请定义另一个类属性(例如 XXXXXX-btn)。请注意,这些类不需要在 CSS 文件中。它们仅用于 JQuery 来查找控件并捕获事件。

IEnumerable<WebGridColumn> cols = 
            new List<WebGridColumn> {
                new WebGridColumn{
                    Format = 
                       @<text>
                       <a href='#' class="display edit-btn">Edit</a>
                       <a href="#" class="edit save-btn">Save</a>
                       <a href="#" class="edit cancel-btn">Cancel</a>
                       <a href="#" class="display delete-btn">Delete</a>
                       </text>
                },
                new WebGridColumn{
                    Header="ID", 
                    Format = @<text>
                                <span class="display">
                                      <label id="lblID">@item.ID</label>
                               </span>
                                <input type="text" id="inID" value="@item.ID" 
                                      class="edit" readonly="true"/>
                            </text>
                },
                new WebGridColumn{
                    Header="First Name", 
                    Format = @<text>
                                <span class="display">
                                      <label id="lblName">@item.Name</label>
                               </span>
                                <input type="text" id="inName" 
                                      value="@item.Name" 
                                      class="edit" />
                              </text>
                },
                new WebGridColumn{
                    Header="Email", 
                    Format = @<text>
                                <span class="display">
                               <label id="lblEmail">@item.Email</label>
                               </span>
                                <input type="text" id="inEmail" 
                                      value="@item.Email" 
                                      class="edit" />
                                </text>
                }
            };

每个数据列在显示和编辑模式下都有两个控件。Label 控件在显示模式下可见,Input 控件在编辑模式下可见。这些控件需要定义在 WebGridColumn 定义的 FORMAT 属性下。Label 控件没有类属性,因此它被包装在 <span> 标签中。

接下来调用 WebGrid 的 GetHtml 方法,以便 Razor 引擎可以为其生成相应的 HTML。在 <div> 标签的末尾,添加以下语句:

@grid.GetHtml(columns:cols, rowStyle:"oddRowStyle", alternatingRowStyle: "evenRowStyle")

如果运行应用程序,此时您可以看到 Label 和 Input 控件的数据都显示在页面上。这是它的示例图片。

在下一节中,您将添加 JQuery 功能来处理显示或编辑的活动模式。

完整代码片段

@model IEnumerable<ManipulateWebGridDemo.Models.Student>
@{
    ViewBag.Title = "Manipulate WebGrid Data";
}
 
<div id="ajaxgrid">
@{
        var grid = new WebGrid(Model, ajaxUpdateContainerId: "ajaxgrid", rowsPerPage: 2);
 
        IEnumerable<WebGridColumn> cols = 
            new List<WebGridColumn> {
                new WebGridColumn{
                    Format = @<text>
                                <a href='#' class="display edit-btn">Edit</a>
                                <a href="#" class="edit save-btn">Save</a>
                                <a href="#" class="edit 
                                      cancel-btn">Cancel</a>
                                <a href="#" class="display 
                                      delete-btn">Delete</a>
                            </text>
                },
                new WebGridColumn{
                    Header="ID", 
                    Format = @<text>
                                <span class="display">
                                      <label id="lblID">@item.ID</label>
                                </span>
                                <input type="text" id="inID" value="@item.ID" 
                                            class="edit" readonly="true"/>
                            </text>
                },
                new WebGridColumn{
                    Header="First Name", 
                    Format = @<text>
                                <span class="display">
                                      <label id="lblName">@item.Name</label>
                                </span>
                                <input type="text" id="inName" 
                                      value="@item.Name" 
                                      class="edit" />
                                </text>
                },
                new WebGridColumn{
                    Header="Email", 
                    Format = @<text>
                          <span class="display">
                               <label id="lblEmail">@item.Email</label>
                           </span>
                                <input type="text" id="inEmail" 
                                      value="@item.Email" 
                                      class="edit" />
                                </text>
                }
            };
}
</div>
@grid.GetHtml(columns:cols, rowStyle:"oddRowStyle", alternatingRowStyle: "evenRowStyle")

6.2 添加 JQuery 方法

您将使用 JQuery 来控制显示和编辑模式。在添加了所有上述 HTML 后,添加一个 <script> 部分,如下所示:

<script type="text/javascript">
    $(function () {
        
    });
</script>

数据操作有三种不同的操作——插入、更新和删除。在接下来的部分中,您将找到所有这三个操作的 JQuery 和 HomeController 代码。

6.2.1 插入记录

WebGrid 在定义时没有访问页脚部分的方法。因此,您需要使用 JQuery 将页脚部分添加到 Razor 为 WebGrid 生成的 HTML 代码中。页脚部分将用于插入记录。插入部分应位于页面索引上方。

定义一个变量 (tfootAdd),其中包含行和所有列。第一列包含所有三个操作命令。其余三列定义 Student 对象的字段。Student 对象的字段在显示模式下不需要可见。因此,您可以使用没有信息的 <span> 标签,并具有 "display" 类属性。<input> 标签用于在编辑模式下捕获用户输入。

// Add row at footer to allow user to add new record
var tfootAdd = "<tr class='tfootrow'>" +
        "<td/>" + 
        "<td> " + 
            "<a href='#' class='display ins-btn' >Insert</a>" +
            "<a href='#' class='edit inssave-btn'>Save</a>" +
            "<a href='#' class='edit cancel-btn'>Cancel</a>" +
        "</td>" +
        "<td>" +
            "<span class='display'/>" +
            "<input type='text' id='inID' value='' class = 'edit'/> " +
        "</td>" +
        "<td>" + 
            "<span class='display'/>" + 
            "<input type='text' id='inName' value='' class = 'edit'/>" + 
        "</td>" +
        "<td>" + 
            "<span class='display'/>" + 
            "<input type='text' id='inEmail' value='' class = 'edit'/>" + 
        "</td>" +
"</tr>"

然后,找到页脚部分 (tfoot) 的第一行,然后添加变量 (tfootAdd)。

$("table tfoot tr:first").before(tfootAdd);

应用程序启动时,WebGrid 的所有行都应处于显示模式。之后,根据用户选择,它应该在每行之间切换显示和编辑模式。为了实现这一点,请添加以下 JQuery,它将查找所有具有 'edit' 类属性的控件并隐藏它们。

$('.edit').hide();  // default is display

当用户单击行的 Insert 和/或 Edit 按钮时,该特定行应切换到编辑模式。在编辑模式下,如果用户单击 Cancel 按钮,则该行应返回到显示模式。使用 "ins-btn"、"edit-btn" 和 "cancel-btn" 属性捕获 Insert、Edit 和 Cancel 按钮的 click 事件。在 click 事件中,找到 Insert、Edit 或 Cancel 的父行。然后找到行的 "edit" 和 "display" 属性,并调用 JQuery 的 toggle 函数。JQuery 的 toggle 函数将切换显示模式。

$('.ins-btn, .edit-btn, .cancel-btn').on("click", function () {
            var tr = $(this).parents('tr:first');
            tr.find('.edit, .display').toggle();
});

使用 JQuery 捕获 Insert 的 Save 操作的 Click 事件,然后调用 HomeController 的方法来保存数据。首先,定义 Save 按钮 (inssave-btn) 的单击方法。在此函数中,获取 ID、Name 和 Email 的数据。使用这些数据,您需要创建一个 Student 对象,该对象将用于将数据发送到 HomeControllerInsertData 方法(稍后介绍)。HomeControllerInsertData 方法将使用 JQuery 的 Ajax 函数调用。InsertData 方法将返回 1 表示成功,0 表示错误。这些值将被捕获在 isSuccess 变量中。当插入过程完成后,Ajax 函数将调用 done 事件。如果 InsertData 方法返回 success,则会显示 success 消息,返回显示模式并刷新页面。否则,它将显示 error 消息并保持在编辑模式。

        $('.inssave-btn').on("click", function () {
            var tr = $(this).parents('tr:first');
            var name = tr.find("#inName").val();
            var id = tr.find("#inID").val();
            var email = tr.find("#inEmail").val();
            var isSuccess = -1;
 
            var Student =
            {
                "ID": id,
                "Name": name,
                "email": email
            };
 
            $.ajax({
 
            // HomeController and InsertData method
                
                url: '/Home/InsertData/',       
            
                data: JSON.stringify(Student),  
 
                type: 'POST',
 
                contentType: 'application/json; charset=utf-8',
 
                success: function (result) {
                    isSuccess = result;
 
                },
                error: function(result){
                    isSuccess = result;
                }
 
            }).done(function () {
                if (isSuccess == "1") {           // Successfully saved
                    tr.find('.edit, .display').toggle();
                    alert("Successfully Saved");
                    location.reload();      // refresh the page
                }
                else {                      // Data Error
                    alert("Error. Please, check the data");
                }
            });
        });

现在,修改 HomeController 并添加 InsertData 方法。这是一个简单的方法,它检查 ID 是否重复。如果 ID 重复,则返回错误 (0) 值,否则将 student 对象添加到 Students 列表中。由于 Ajax 函数是通过 POST 调用的,因此您需要为 InsertData 方法设置 HttpPost 的方法属性。

        [HttpPost]
        public JsonResult InsertData(Models.Student inStudent)
        {
            String result = String.Empty;
 
            Models.Student dup = Students.Find(p => p.ID == inStudent.ID);
 
            if (dup == null)
            {
                Students.Add(inStudent);
                result = "1";
            }
            else
            {
                result = "0";
            }
 
            return Json(result, JsonRequestBehavior.AllowGet);
        }

6.2.2 更新记录

当用户单击 Edit 按钮时,该行数据将处于编辑模式,用户可以修改数据。编辑数据后,当用户单击 Save 按钮时,您需要使用 Ajax 函数调用 HomeControllerSaveData 方法。首先,定义 Save 按钮 (save-btn) 的 click 方法。在此函数中,获取 ID、Name 和 Email 的数据。使用这些数据,创建一个 Student 对象,该对象将用于将数据发送到 HomeControllerSaveData 方法(稍后介绍)。现在使用 Ajax 函数调用 HomeControllerSaveData 方法。SaveData 方法将返回 1 表示 success0 表示 error。这些值将被捕获在 isSuccess 变量中。当更新过程完成后,Ajax 函数将调用 done 事件。如果 SaveData 方法返回 success,则需要返回显示模式并刷新页面。否则,将显示 error 消息。

        $('.save-btn').on("click", function () {

            var tr = $(this).parents('tr:first');
            var name = tr.find("#inName").val();
            var id = tr.find("#inID").val();
            var email = tr.find("#inEmail").val();
            var isSuccess = -1;
 
            tr.find("#lblName").text(name);
            tr.find("#lblEmail").text(email);
 
            var Student =
            {
                "ID": id,
                "Name": name,
                "email": email
            };
 
            $.ajax({
 
                url: '/Home/SaveData/',
                data: JSON.stringify(Student),
                type: 'POST',
                contentType: 'application/json; charset=utf-8',
                success: function (result) {
                    isSuccess = result;
                },
                error: function (result) {
                    isSuccess = result;
                }

            }).done(function () {
                if (isSuccess == "1") {           // Successfully saved
                    tr.find('.edit, .display').toggle();
                    alert("Successfully Saved");
                }
                else {                      // Data Error
                    alert("Error. Please, check the data");
                }
            });
        });

现在,修改 HomeController 并添加 SaveData 方法。这是一个简单的方法,它使用 ID 查找现有的 Student 对象。如果 Student 对象不存在,则返回 error,否则将更新 student 对象。由于 Ajax 函数是通过 POST 调用的,因此您需要为 SaveData 方法设置 HttpPost 的方法属性。

        [HttpPost]
        public JsonResult SaveData(Models.Student student)
        {
            int index = 0;
            String result = String.Empty;
 
            index = Students.FindIndex(p => p.ID == student.ID);
            if (index >= 0)
            {
                Students[index] = student;
                result = "1";
            }
            else
                result = "0";
 
            return Json(result, JsonRequestBehavior.AllowGet);
        }

6.2.3 删除记录

当用户单击 Delete 按钮时,该行数据将被删除。这将调用 Delete (delete-btn) 方法。在此函数中,获取 ID、Name 和 Email 的数据。使用这些数据,创建一个 Student 对象,该对象将用于将数据发送到 HomeControllerDeleteData 方法(稍后介绍)。使用 Ajax 函数调用 HomeControllerDeleteData 方法。DeleteData 方法将返回 1 表示成功,0 表示错误。这些值将被捕获在 isSuccess 变量中。当删除过程完成后,Ajax 函数将调用 done 事件。如果 DeleteData 方法返回 success,则需要刷新页面。否则,将显示 error 消息。

$('.delete-btn').on("click", function () {
 
            var tr = $(this).parents('tr:first');
            var name = tr.find("#inName").val();
            var id = tr.find("#inID").val();
            var email = tr.find("#inEmail").val();
            var isSuccess = -1;
 
            var Student =
            {
                "ID": id,
                "Name": name,
                "email": email
            };
 
            $.ajax({
 
                url: '/Home/DeleteData/',
 
                data: JSON.stringify(Student),
 
                type: 'POST',
 
                contentType: 'application/json; charset=utf-8',
 
                success: function (result) {
                    isSuccess = result;
 
                },
                error: function (result) {
                    isSuccess = result;
                }
 
            }).done(function () {
                if (isSuccess == "1") {           // Successfully Deleted
                    alert("Successfully Deleted");
                    location.reload();      // refresh the page
                }
                else {                      // Data Error
                    alert("Error. Please, check the data");
                }
 
            });

        });

修改 HomeController 并添加 DeleteData 方法。这是一个简单的方法,它使用 ID 查找现有的 Student 对象。如果 Student 对象不存在,则返回 error,否则将删除 student 对象。由于 Ajax 函数是通过 POST 调用的,因此您需要为 DeleteData 方法设置 HttpPost 的方法属性。

        [HttpPost]
        public JsonResult DeleteData(Models.Student student)
        {
            String result = String.Empty;
 
            Models.Student s = Students.Find(p => p.ID == student.ID);
            if (s != null)
            {
                Students.Remove(s);
                result = "1";
            }
            else
                result = "0";
 
            return Json(result, JsonRequestBehavior.AllowGet);
        }

7.0 结论

VC 和 JQuery 一起使得为 WebGrid 实现数据编辑变得非常容易。您可以将相同的逻辑用于编辑表而不是 WebGrid 中的数据。但是,如果您使用表,则需要从代码中维护页面索引。

© . All rights reserved.