使用 ASP.NET MVC 和 jQuery 实现单页应用程序






4.83/5 (3投票s)
在本文中,我将向您解释如何使用 asp.net mvc、jquery 和 sammy.js 实现单页应用程序。
引言
在本文中,我将告诉您如何使用 ASP.NET MVC 和 jQuery 创建单页应用程序。 在不使用 Angular、React 和其他第三方 JavaScript 的情况下,实现 SPA 比较困难。 在本文中,我将仅解释控制器和 UI 级别的交互。 我跳过了数据访问层。 如果您需要,请下载附件,其中包含应用程序的完整代码。
注意 - 我使用了代码优先方法进行 CRUD 操作。 下载项目文件后,请还原程序包,更改 web.config 中的连接字符串,并在包管理器控制台中运行 update-database 命令。
背景
所需内容
- ASP.NET MVC
- JQUERY
- Sammy.JS(用于路由)
使用代码
创建一个新的 MVC 项目。
将 jQuery 和 Sammy.js 引用添加到您的布局页面。 添加 div 标签 (MainContent),我们将在其中渲染所有部分视图。
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - My ASP.NET Application</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") <script src="~/Scripts/jquery-1.10.2.js"></script> <script src="~/Scripts/sammy-0.7.4.js"></script> </head>
在您的项目中创建 layout-routing.js 文件,其中包含您的应用程序路由结构,如下所示。
var mainContent; var titleContent; $(function () { mainContent = $("#MainContent"); /// render partial views. titleContent = $("title"); // render titles. }); var routingApp = $.sammy("#MainContent", function () { this.get("#/Student/Index", function (context) { titleContent.html("Student Page"); $.get("/Student/Index", function (data) { context.$element().html(data); }); }); this.get("#/Student/Add", function (context) { titleContent.html("Add Student"); //$("#BigLoader").modal('show'); // If you want to show loader $.get("/Student/Add", function (data) { //$("#BigLoader").modal('hide'); context.$element().html(data); }); }); this.get("#/Student/Edit", function (context) { titleContent.html("Edit Student"); $.get("/Student/Edit", { studentID: context.params.id // pass student id }, function (data) { context.$element().html(data); }); }); this.get("#/Home/About", function (context) { titleContent.html("About"); $.get("/Home/About", function (data) { context.$element().html(data); }); }); this.get("#/Home/Contact", function (context) { titleContent.html("Contact"); $.get("/Home/Contact", function (data) { context.$element().html(data); }); }); }); $(function () { routingApp.run("#/Student/Index"); // default routing page. }); function IfLinkNotExist(type, path) { if (!(type != null && path != null)) return false; var isExist = true; if (type.toLowerCase() == "get") { if (routingApp.routes.get != undefined) { $.map(routingApp.routes.get, function (item) { if (item.path.toString().replace("/#", "#").replace(/\\/g, '').replace("$/", "").indexOf(path) >= 0) { isExist = false; } }); } } else if (type.toLowerCase() == "post") { if (routingApp.routes.post != undefined) { $.map(routingApp.routes.post, function (item) { if (item.path.toString().replace("/#", "#").replace(/\\/g, '').replace("$/", "").indexOf(path) >= 0) { isExist = false; } }); } } return isExist; }
IfLinkNotExist() 检查 URL 是否不应重复,之后我们将动态 URL 添加到页面加载时的路由列表中。
在 _layout.cshtml 页面中添加 layout-routing 引用。
<script src="~/layout-routing.js"></script> @*@Scripts.Render("~/bundles/jquery")*@ @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false)
添加一个新的控制器 ‘WelcomeController’,该控制器只有一个操作 ‘Index’。
namespace MvcSpaDemo.Controllers { public class WelcomeController : Controller { public ActionResult Index() { return View(); } } }
使用右键单击创建 ‘Index’ 操作的视图。
在该视图中,附加布局页面链接。(我们需要第一次渲染布局页面)。
@{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h1>Welcome</h1>
现在,创建 Student Controller,其中包含 Student CRUD 操作模块(添加、更新、删除、查看)。
查看学生
public ActionResult Index() { return PartialView(); } public ActionResult _Index() { var students = StudentData.GetStudents(); return PartialView(students); }
添加两个没有布局页面的视图。 一个用于外部学生内容,如标题、添加按钮等,另一个用于学生表格。
Index.cshtml
@{ Layout = null; } <h4>Students</h4> <div class="row"> <a href="#/Student/Add">Add Student</a> </div> <div class="row"> <div id="StudentDiv"> </div> </div> <script> $(function () { GetStudents(); }); function GetStudents() { $.get("/Student/_Index/", function (data) { $("#StudentDiv").html(data); }); } function DeleteStudent(studentID) { if (confirm("Delete student?")) { $.get("/Student/Delete/", { studentID: studentID }, function (data) { GetStudents(); }); } } </script>
_Index.cshtml
@model IEnumerable<MvcSpaDemo.Entities.Student> @{ Layout = null; } <table class="table table-striped table-bordered"> <thead> <tr> <th>ID</th> <th>Name</th> <th>Email</th> <th>Class</th> <th>Action</th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td>@item.StudentID</td> <td>@item.FirstName @item.LastName</td> <td>@item.Email</td> <td>@item.Class</td> <td> <a href="#/Student/Edit?id=@item.StudentID">Edit</a> <a href="javascript::;" onclick="DeleteStudent('@item.StudentID')">Delete</a> </td> </tr> } </tbody> </table>
更改 RouteConfig.cs 中的默认控制器和操作。
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Welcome", action = "Index", id = UrlParameter.Optional } ); } }
使用 F5 运行应用程序。 同样为 About 和 Contact 页面执行相同的路由。
添加学生 asd
现在,在 Controller 中添加“创建学生操作”。
public ActionResult Add() { var student = new Student(); ViewBag.Status = "Add"; return PartialView(student); } [HttpPost] public ActionResult Create(Student student) { StudentData.AddStudent(student); return Json(true, JsonRequestBehavior.AllowGet); }
我们将添加带有动态路由脚本的添加页面,用于创建或更新。
@model MvcSpaDemo.Entities.Student @{ ViewBag.Title = "Add"; Layout = null; // We use same page for add and edit. var urlPostString = "/Student/Create"; if (ViewBag.Status == "Edit") { urlPostString = "/Student/Update"; } } <h2>@ViewBag.Status Student</h2> <form id="frmStudent" name="frmStudent" method="post" action="#@urlPostString"> @Html.HiddenFor(x => x.StudentID) <div class="row"> <div class="form-group"> <label for="Variables">First Name</label> @Html.TextBoxFor(x => x.FirstName, new { @class = "form-control square" }) </div> <div class="form-group"> <label for="Variables">Last Name</label> @Html.TextBoxFor(x => x.LastName, new { @class = "form-control square" }) </div> <div class="form-group"> <label for="Variables">Email</label> @Html.TextBoxFor(x => x.Email, new { @class = "form-control square" }) </div> <div class="form-group"> <label for="Variables">Class</label> @Html.TextBoxFor(x => x.Class, new { @class = "form-control square" }) </div> <div class="form-group"> <input type="submit" class="btn btn-primary" value="Submit" /> </div> </div> </form> <script> $("#frmStudent").on("submit", function (e) { debugger; //if ($("#frmStudent").valid()) { routingApp.runRoute('post', '#@urlPostString'); e.preventDefault(); e.stopPropagation(); //} }); // add dynamic create or update link debugger; if (IfLinkNotExist("POST", "#@urlPostString")) { routingApp.post("#@urlPostString", function (context) { //$("#BigLoader").modal('show'); var formData = new FormData($('#frmStudent')[0]); $.ajax({ url: '@urlPostString', data: formData, type: "POST", contentType: false, processData: false, success: function (data) { //$("#BigLoader").modal('hide'); if (data) { if ('@ViewBag.Status' == 'Add') alert("Student successfully added"); else if ('@ViewBag.Status' == 'Edit') alert("Student successfully updated"); window.location.href = "#/Student/Index"; } else { alert('Something went wrong'); } }, error: function () { alert('Something went wrong'); } }); }); } </script>
现在,运行应用程序。
编辑学生
现在,进入编辑模块。 在 Controller 中添加编辑操作。
public ActionResult Edit(int studentID) // studentID nothing but parameter name which we pass in layout-routing. { var student = StudentData.GetStudentById(studentID); ViewBag.Status = "Edit"; return PartialView("Add", student); } [HttpPost] public ActionResult Update(Student student) { StudentData.UpdateStudent(student); return Json(true, JsonRequestBehavior.AllowGet); }
我们为添加和编辑使用了相同的部分视图,因此无需为编辑创建新的视图。
添加操作方法后,只需运行应用程序即可。
删除学生
现在,我们将实现删除操作。
我们已经在 Student Index.cshtml 中编写了删除按钮的代码。
function GetStudents() { $.get("/Student/_Index/", function (data) { $("#StudentDiv").html(data); }); } function DeleteStudent(studentID) { if (confirm("Delete student?")) { $.get("/Student/Delete/", { studentID: studentID }, function (data) { GetStudents(); }); } }
运行应用程序。
我希望您喜欢这篇文章。 欢迎您对本文提出宝贵的反馈、问题或评论。