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

在MVC4应用程序中使用Knockout.JS和EntityFramework 5完成端到端CRUD操作

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (29投票s)

2013 年 12 月 13 日

CPOL

11分钟阅读

viewsIcon

199612

downloadIcon

1881

本文将作为教程,解释如何在MVC4应用程序中设置Knockout.js环境,该环境也能够执行CRUD操作

一)介绍 

我一直在浏览多个网站,查看是否能找到一个完整的关于使用Knockout.JS和MVC 4进行CRUD操作的端到端教程或文章。不幸的是,我找到的所有教程都不完整或解释过于简短。在我的上一篇文章中,我们学习了如何在ASP.NET Web Forms中使用MVC和EntityFramework进行CRUD。本文是同一系列的延续。本文将作为教程,解释如何在MVC4应用程序中设置Knockout.JS环境,该环境也能够执行CRUD操作。 

二)我们的路线图

我们将按照以下议程学习Knockout.JS,

  1. 第一部分:Knockout.js简介以及在Asp.Net Web Forms中使用Knockout.JS和Entity Framework进行CRUD操作。
  2. 第二部分:在MVC4应用程序中使用Knockout.JS和Entity Framework完成端到端CRUD操作。

三)第二部分:在MVC4应用程序中使用Knockout.JS和Entity Framework完成端到端CRUD操作

我们将在这篇文章中逐步讨论KO

  1. 创建MVC应用程序。
  2. 使用Entity Framework 5创建CRUD操作方法。
  3. 使用MVC4和Entity Framework 5执行CRUD操作
  4. 将Knockout.JS添加到我们的MVC应用程序。
  5. 在我们的MVC 4应用程序中使用KO执行CRUD操作。

在我们开始之前,我不想深入理论,而是想简单介绍一下MVC、Entity Framework和Knockout。

四)MVC

模型:应用程序整体操作的业务实体。许多应用程序使用持久性存储机制(如数据库)来存储数据。MVC没有特别提及数据访问层,因为人们认为它被模型封装了。

视图 (View):将模型呈现为交互形式的用户界面。

控制器 (Controller):处理来自视图的请求并更新导致模型状态更改的模型。

要在.NET中实现MVC,我们主要需要三个类(视图、控制器和模型)。

五)Entity Framework

让我们看看微软对Entity Framework的标准定义

"Microsoft ADO.NET Entity Framework是一个对象/关系映射(ORM)框架,它使开发人员能够将关系数据作为特定领域对象进行操作,从而消除了开发人员通常需要编写的大部分数据访问管道代码。使用Entity Framework,开发人员可以使用LINQ发出查询,然后以强类型对象的形式检索和操作数据。Entity Framework的ORM实现提供了诸如更改跟踪、身份解析、延迟加载和查询转换等服务,因此开发人员可以专注于其特定于应用程序的业务逻辑,而不是数据访问基础知识。"

简单来说,Entity Framework是一个对象/关系映射(ORM)框架。它是ADO.NET的增强版,是ADO.NET的一个上层,为开发人员提供了一种自动机制,用于访问和存储数据库中的数据。

希望这能让您对ORM和EntityFramework有一个初步的了解。

六)Knockout.JS

Knockout.JS (KO) 本质上是一个 JS 库,它通过遵循观察者模式的“可观察”视图模型,在客户端(浏览器)上实现声明性绑定,使得 UI 能够在数据绑定被修改时自动绑定和刷新自身。Knockout.JS 提供了自己的模板模式,帮助我们轻松绑定视图模型数据。KO 遵循 MVVM 模式,即 Model-View-View Model。

如架构所示,视图以双向绑定的方式与视图模型交互,即当模型更改时,视图会自行更新;当视图更新时,模型会立即自行更新。 

KO 提供 3 个最重要的功能,例如,

Knockout Akhil

KO 的整个理念都源于这三个主要功能。KO 还帮助开发单页应用程序(SPA)。SPA 是当今时代开发富互联网应用程序(RIA)的全新方式。

七)应用程序架构

knockout Architecture by Akhil Mittal

 

该架构非常不言自明。应用程序采用客户端-服务器模型,其中我们的MVC应用程序或Web API应用程序(本教程未涵盖)将在服务器端与EntityFramework层交互。EntityFramework层将负责与数据库进行数据事务。

在客户端,我们有HTML模板,它将通过Ajax调用与服务器通信,并且模板将通过JSON对象通过knockout observables(已在第一部分讨论)绑定到数据。

八)MVC应用程序

1. 步骤1:创建名为LearningKO的数据库,并向其中添加一个名为student的表,表的脚本如下:

USE [LearningKO]
GO
/****** Object:  Table [dbo].[Student]    Script Date: 12/04/2013 23:58:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Student](
	[StudentId] [nvarchar](10) NOT NULL,
	[FirstName] [nvarchar](50) NULL,
	[LastName] [nvarchar](50) NULL,
	[Age] [int] NULL,
	[Gender] [nvarchar](50) NULL,
	[Batch] [nvarchar](50) NULL,
	[Address] [nvarchar](50) NULL,
	[Class] [nvarchar](50) NULL,
	[School] [nvarchar](50) NULL,
	[Domicile] [nvarchar](50) NULL,
 CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED 
(
	[StudentId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT [dbo].[Student] ([StudentId], [FirstName], [LastName], [Age], [Gender], [Batch], [Address], [Class], [School], [Domicile]) VALUES (N'1', N'Akhil', N'Mittal', 28, N'Male', N'2006', N'Noida', N'Tenth', N'LFS', N'Delhi')
INSERT [dbo].[Student] ([StudentId], [FirstName], [LastName], [Age], [Gender], [Batch], [Address], [Class], [School], [Domicile]) VALUES (N'2', N'Parveen', N'Arora', 25, N'Male', N'2007', N'Noida', N'8th', N'DPS', N'Delhi')
INSERT [dbo].[Student] ([StudentId], [FirstName], [LastName], [Age], [Gender], [Batch], [Address], [Class], [School], [Domicile]) VALUES (N'3', N'Neeraj', N'Kumar', 38, N'Male', N'2011', N'Noida', N'10th', N'MIT', N'Outside Delhi')
INSERT [dbo].[Student] ([StudentId], [FirstName], [LastName], [Age], [Gender], [Batch], [Address], [Class], [School], [Domicile]) VALUES (N'4', N'Ekta', N'Mittal', 25, N'Female', N'2005', N' Noida', N'12th', N'LFS', N'Delhi')

  • 步骤2:打开您的Visual Studio(Visual Studio版本应大于或等于12)并添加一个MVC Internet应用程序,

    我给它命名为“KnockoutWithMVC4”。

  • 步骤3:您将获得一个完整的结构化MVC应用程序,其中在Controller文件夹中包含默认的Home控制器。默认情况下,Entity Framework作为包下载到应用程序文件夹中,但如果未下载,您可以通过右键单击项目,选择“管理NuGet包”并搜索并安装Entity Framework来添加Entity Framework包,

    4. 步骤4:右键单击项目文件,选择“添加新项”并添加ADO.NET实体数据模型。按照以下向导中的步骤操作,

    从数据库生成模型,选择您的服务器和LearningKO数据库名称,连接字符串将自动添加到您的Web.Config,将该连接字符串命名为LearningKOEntities。 

    选择要添加到模型中的表。在本例中是Student表。

  • 步骤5:现在向Controller文件夹添加一个新的控制器,右键单击Controller文件夹并添加一个名为Student的控制器。由于我们已经创建了数据模型,我们可以选择通过选择的Entity Framework数据模型创建CRUD操作的选项,

  • 将控制器命名为StudentController,
  • 从支架选项中,选择“带读/写操作和视图的MVC控制器,使用Entity Framework”。
  • 选择模型类为Student,它位于我们的解决方案中。
  • 选择数据上下文类为LearningKOEntities,当我们在解决方案中添加EF数据模型时,它会添加到我们的解决方案中。
  • 选择Razor作为视图的渲染引擎。
  • 单击高级选项,选择布局或主页,然后从共享文件夹中选择_Layout.cshtml。

  • 步骤6:我们看到学生控制器已准备好所有CRUD操作,如下所示,
    7.	using System;
    8.	using System.Collections.Generic;
    9.	using System.Data;
    10.	using System.Data.Entity;
    11.	using System.Linq;
    12.	using System.Web;
    13.	using System.Web.Mvc;
    14.	
    15.	namespace KnockoutWithMVC4.Controllers
    16.	{
    17.	    public class StudentController : Controller
    18.	    {
    19.	        private LearningKOEntities db = new LearningKOEntities();
    20.	
    21.	        //
    22.	        // GET: /Student/
    23.	
    24.	        public ActionResult Index()
    25.	        {
    26.	            return View(db.Students.ToList());
    27.	        }
    28.	
    29.	        //
    30.	        // GET: /Student/Details/5
    31.	
    32.	        public ActionResult Details(string id = null)
    33.	        {
    34.	            Student student = db.Students.Find(id);
    35.	            if (student == null)
    36.	            {
    37.	                return HttpNotFound();
    38.	            }
    39.	            return View(student);
    40.	        }
    41.	
    42.	        //
    43.	        // GET: /Student/Create
    44.	
    45.	        public ActionResult Create()
    46.	        {
    47.	            return View();
    48.	        }
    49.	
    50.	        //
    51.	        // POST: /Student/Create
    52.	
    53.	        [HttpPost]
    54.	        [ValidateAntiForgeryToken]
    55.	        public ActionResult Create(Student student)
    56.	        {
    57.	            if (ModelState.IsValid)
    58.	            {
    59.	                db.Students.Add(student);
    60.	                db.SaveChanges();
    61.	                return RedirectToAction("Index");
    62.	            }
    63.	
    64.	            return View(student);
    65.	        }
    66.	
    67.	        //
    68.	        // GET: /Student/Edit/5
    69.	
    70.	        public ActionResult Edit(string id = null)
    71.	        {
    72.	            Student student = db.Students.Find(id);
    73.	            if (student == null)
    74.	            {
    75.	                return HttpNotFound();
    76.	            }
    77.	            return View(student);
    78.	        }
    79.	
    80.	        //
    81.	        // POST: /Student/Edit/5
    82.	
    83.	        [HttpPost]
    84.	        [ValidateAntiForgeryToken]
    85.	        public ActionResult Edit(Student student)
    86.	        {
    87.	            if (ModelState.IsValid)
    88.	            {
    89.	                db.Entry(student).State = EntityState.Modified;
    90.	                db.SaveChanges();
    91.	                return RedirectToAction("Index");
    92.	            }
    93.	            return View(student);
    94.	        }
    95.	
    96.	        //
    97.	        // GET: /Student/Delete/5
    98.	
    99.	        public ActionResult Delete(string id = null)
    100.	        {
    101.	            Student student = db.Students.Find(id);
    102.	            if (student == null)
    103.	            {
    104.	                return HttpNotFound();
    105.	            }
    106.	            return View(student);
    107.	        }
    108.	
    109.	        //
    110.	        // POST: /Student/Delete/5
    111.	
    112.	        [HttpPost, ActionName("Delete")]
    113.	        [ValidateAntiForgeryToken]
    114.	        public ActionResult DeleteConfirmed(string id)
    115.	        {
    116.	            Student student = db.Students.Find(id);
    117.	            db.Students.Remove(student);
    118.	            db.SaveChanges();
    119.	            return RedirectToAction("Index");
    120.	        }
    121.	
    122.	        protected override void Dispose(bool disposing)
    123.	        {
    124.	            db.Dispose();
    125.	            base.Dispose(disposing);
    126.	        }
    127.	    }
    128.	} 
  • 7. 步骤7:打开App_Start文件夹,并将控制器名称从Home更改为Student,

    代码将变为:

         public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
                routes.MapRoute(
                    name: "Default",
                    url: "{controller}/{action}/{id}",
                    defaults: new { controller = "Student", action = "Index", id = UrlParameter.Optional }
                );
            }
  • 步骤8:现在按F5运行应用程序,您将看到我们在创建表时添加到Student表中的所有学生列表。由于CRUD操作是自动编写的,我们有用于显示列表以及其他编辑、删除和创建操作的动作结果。请注意,所有操作的视图都在Views文件夹下的Student文件夹中创建。

     

    现在,您可以对该列表执行所有操作。

     

     

    由于我没有对模型或创建现有学生ID进行任何验证检查,代码可能会中断,因此当发现ID已存在时,我在创建中调用Edit Action,

     

    现在创建新学生,

     

    我们看到学生已成功创建并添加到列表中,

     

    在数据库中,

     

    对于编辑也类似,

     

    更改任何字段并按保存。更改将反映在列表和数据库中,

     

    用于删除, 

     

    学生已删除。

    在数据库中,

     

    所以,就这样,我们的第一个任务完成了,即创建一个MVC应用程序,并使用Entity Framework 5执行CRUD操作。您可以看到,到目前为止,我们还没有编写一行代码。是的,这就是MVC和EF的魔力。干杯!

     

    九)Knockout应用程序

    我们的第一个任务完成得很顺利,现在我们转向我们的主要目标,即KO。由于KO在很大程度上依赖于MVVM模式,我们将在客户端使用MVVM,并使用我们的控制器作为相同的,只是对返回JSON逻辑进行了一些修改。您可以在本系列文章的第一部分了解MVVM模式和KO理论。

    1. 步骤 1

      JQuery 和 Knockout.js 文件在解决方案的脚本文件夹中非常重要。检查它们,如果找不到它们,则以与添加 Entity Framework 相同的方式添加 jQuery 和 Knockout 的包。右键单击项目,选择“管理 NuGet 包”并搜索 jQuery 然后安装,然后搜索 knockout 包并安装,

       

       

    2. 步骤2:右键单击Scripts文件夹并创建一个名为ViewModel的文件夹。向该文件夹添加四个js文件,分别命名为CreateVM.jsEditVM.jsDeleteVM.jsStudentListVM.js。这些是添加到与控制器通信并渲染我们视图模板的视图模型文件。

       

    3. 步骤3:将一些代码添加到CreateVm.js中,如下所示:

       

      var urlPath = window.location.pathname;
      $(function () {
          ko.applyBindings(CreateVM);
      });
      
      var CreateVM = {
          Domiciles: ko.observableArray(['Delhi', 'Outside Delhi']),
          Genders: ko.observableArray(['Male', 'Female']),
          Students: ko.observableArray([]),
          StudentId: ko.observable(),
          FirstName: ko.observable(),
          LastName: ko.observable(),
          Age: ko.observable(),
          Batch: ko.observable(),
          Address: ko.observable(),
          Class: ko.observable(),
          School: ko.observable(),
          Domicile: ko.observable(),
          Gender: ko.observable(),
          SaveStudent: function () {
              $.ajax({
                  url: '/Student/Create',
                  type: 'post',
                  dataType: 'json',
                  data: ko.toJSON(this),
                  contentType: 'application/json',
                  success: function (result) {
                  },
                  error: function (err) {
                      if (err.responseText == "Creation Failed")
                      { window.location.href = '/Student/Index/'; }
                      else {
                          alert("Status:"+err.responseText);
                          window.location.href = '/Student/Index/';;
                      }
                  },
                  complete: function () {
                      window.location.href = '/Student/Index/';
                  }
              });
          }
      };

      在文档加载时,我们为CreateVM应用绑定,然后在视图模型方法内部,我们将可观察对象初始化为Student的属性,这些属性将绑定到相应的视图。您可以在系列的第一部分阅读更多关于KO中的可观察对象。有一个保存函数,它向Student Controller的Create方法发送一个ajax请求,并获取字符串结果。data: ko.toJSON(this)表示以JSON格式将对象发送到控制器方法。

      Student/Create 控制器方法

      修改Create的控制器方法代码,使其向调用者返回JSON。与对象绑定的HTML模板实际上绑定到通过Knockout Observables在视图模型方法中设置的json属性。 

      它遵循观察者模式,因此当模型更新时,视图会自动更新,当视图更新时,模型也会自行更新,这称为双向绑定。

      Controller 代码

             [HttpPost]
              public string Create(Student student)
              {
                  if (ModelState.IsValid)
                  {
                      if (!StudentExists(student))
                          db.Students.Add(student);
                      else
                          return Edit(student);
                      db.SaveChanges();
                      return "Student Created";
                  }
                  return "Creation Failed";
              }

      视图代码

      更改已创建视图的代码以与KO配合使用,

      对于create.cshtml,

      <h2>Create</h2>
      <fieldset>
          <legend>Create Student</legend>
      
          <div class="editor-label">
              Student id
          </div>
          <div class="editor-field">
              <input data-bind="value: StudentId" />
          </div>
      
          <div class="editor-label">
              First Name
          </div>
          <div class="editor-field">
              <input data-bind="value: FirstName" />
          </div>
      
          <div class="editor-label">
              Last Name
          </div>
          <div class="editor-field">
              <input data-bind="value: LastName" />
          </div>
      
          <div class="editor-label">
              Age
          </div>
          <div class="editor-field">
              <input data-bind="value: Age" />
          </div>
      
          <div class="editor-label">
              Gender
          </div>
          <div class="editor-field">
              <select data-bind="options: Genders, value: Gender, optionsCaption: 'Select Gender...'"></select>
          </div>
      
          <div class="editor-label">
              Batch
          </div>
          <div class="editor-field">
              <input data-bind="value: Batch" />
          </div>
      
          <div class="editor-label">
              Address
          </div>
          <div class="editor-field">
              <input data-bind="value: Address" />
          </div>
      
          <div class="editor-label">
              Class
          </div>
          <div class="editor-field">
              <input data-bind="value: Class" />
          </div>
      
          <div class="editor-label">
              School
          </div>
          <div class="editor-field">
              <input data-bind="value: School" />
          </div>
      
          <div class="editor-label">
              Domicile
          </div>
          <div class="item ">
              <select data-bind="options: Domiciles, value: Domicile, optionsCaption: 'Select Domicile...'"></select>
          </div>
      
          <p>
              <button type="button" data-bind="click: SaveStudent">Save Student To Database</button>
          </p>
      </fieldset>
      <div>
          <a href="@Url.Action("Index", "Student")" >Back to List</a>
      </div>
      
      @section Scripts {
          @Scripts.Render("~/Scripts/ViewModels/CreateVM.js")
      }

      您可以看到我使用了HTML5的data-bind属性将视图元素绑定到视图模型属性,例如data-bind="value: StudentId",这适用于所有可编辑元素。单击按钮绑定到视图模型的SaveStudent方法。

      在页面的末尾,我们通过以下方式为这个特定的视图注册了CreateVM.js视图模型:

      @section Scripts {
          @Scripts.Render("~/Scripts/ViewModels/CreateVM.js")
      }

      标签。

    4. 步骤3:我们对所有视图、视图模型和控制器方法执行相同的操作集,代码如下:

       

    用于编辑

    ViewModel

    代码添加到StudentListVM中,用于Edit View Model,因为它只在加载时执行获取操作。

    控制器方法

    public ActionResult Edit(string id=null)
            {
                Student student = db.Students.Find(id);
                if (student == null)
                {
                    return null;
                }
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                ViewBag.InitialData = serializer.Serialize(student); 
                return View();
            }
    
            /// <summary>
            /// Edits particular student details
            /// </summary>
            /// <param name="student"></param>
            /// <returns></returns>
            [HttpPost]
            public string Edit(Student student)
            {
                if (ModelState.IsValid)
                {
                    db.Entry(student).State = EntityState.Modified;
                    db.SaveChanges();
                    return "Student Edited";
                }
                return "Edit Failed";
            }

    视图

    <h2>Edit</h2>
    <fieldset>
        <legend>Edit Student</legend>
    
        <div class="editor-label">
            Student id
        </div>
        <div class="editor-field">
            <input data-bind="value: StudentId" readonly="readonly" />
        </div>
    
        <div class="editor-label">
            First Name
        </div>
        <div class="editor-field">
            <input data-bind="value: FirstName" />
        </div>
    
        <div class="editor-label">
            Last Name
        </div>
        <div class="editor-field">
            <input data-bind="value: LastName" />
        </div>
    
        <div class="editor-label">
            Age
        </div>
        <div class="editor-field">
            <input data-bind="value: Age" />
        </div>
    
        <div class="editor-label">
            Gender
        </div>
        <div class="editor-field">
            <select data-bind="options: Genders, value: Gender, optionsCaption: 'Select Gender...'"></select>
        </div>
    
        <div class="editor-label">
            Batch
        </div>
        <div class="editor-field">
            <input data-bind="value: Batch" />
        </div>
    
        <div class="editor-label">
            Address
        </div>
        <div class="editor-field">
            <input data-bind="value: Address" />
        </div>
    
        <div class="editor-label">
            Class
        </div>
        <div class="editor-field">
            <input data-bind="value: Class" />
        </div>
    
        <div class="editor-label">
            School
        </div>
        <div class="editor-field">
            <input data-bind="value: School" />
        </div>
    
        <div class="editor-label">
            Domicile
        </div>
        <div class="editor-field">
            <select data-bind="options: Domiciles, value: Domicile, optionsCaption: 'Select Domicile...'"></select>
        </div>
        <p>
            <button type="button" data-bind="click: SaveStudent">Save Student To Database</button>
        </p>
    </fieldset>
    <div>
        <a href="@Url.Action("Index", "Student")">Back to List</a>
    </div>
    @section Scripts {
        <script>
    
            $(function () {
                ko.applyBindings(EditVM);
            });
    
            var initialData = '@Html.Raw(ViewBag.InitialData)'; //get the raw json
            var parsedJSON = $.parseJSON(initialData); //parse the json client side
            var EditVM = {
                Domiciles: ko.observableArray(['Delhi', 'Outside Delhi']),
                Genders: ko.observableArray(['Male', 'Female']),
                Students: ko.observableArray([]),
                StudentId: ko.observable(parsedJSON.StudentId),
                FirstName: ko.observable(parsedJSON.FirstName),
                LastName: ko.observable(parsedJSON.LastName),
                Age: ko.observable(parsedJSON.Age),
                Batch: ko.observable(parsedJSON.Batch),
                Address: ko.observable(parsedJSON.Address),
                Class: ko.observable(parsedJSON.Class),
                School: ko.observable(parsedJSON.School),
                Domicile: ko.observable(parsedJSON.Domicile),
                Gender: ko.observable(parsedJSON.Gender),
                SaveStudent: function () {
                    $.ajax({
                        url: '/Student/Edit',
                        type: 'post',
                        dataType: 'json',
                        data: ko.toJSON(this),
                        contentType: 'application/json',
                        success: function (result) {
                        },
                        error: function (err) {
                            if (err.responseText == "Creation Failed")
                            { window.location.href = '/Student/Index/'; }
                            else {
                                alert("Status:" + err.responseText);
                                window.location.href = '/Student/Index/';;
                            }
                        },
                        complete: function () {
                            window.location.href = '/Student/Index/';
                        }
                    });
                }
            };
    
        </script>
    }

    用于删除

    ViewModel

    代码添加到StudentListVM中,用于Edit View Model,因为它只在加载时执行获取操作。

    控制器方法

           public ActionResult Delete(string id = null)
            {
                Student student = db.Students.Find(id);
                if (student == null)
                {
                    return null;
                }
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                ViewBag.InitialData = serializer.Serialize(student);
                return View();
            }
    
            /// <summary>
            /// Delete particular student details
            /// </summary>
            /// <param name="student"></param>
            /// <returns></returns>
            [HttpPost]
            public string Delete(Student student)
            {
                Student studentDetail = db.Students.Find(student.StudentId);
                db.Students.Remove(studentDetail);
                db.SaveChanges();
                return "Student Deleted";
            }

    视图

    @model KnockoutWithMVC4.Student
    
    @{
        ViewBag.Title = "Delete";
    }
    
    <h2>Delete Student</h2>
    
    <h3>Are you sure you want to delete this?</h3>
    <fieldset>
        <legend>Delete</legend>
        <div class="display-label">
            Student Id
        </div>
        <div class="display-field">
            <input data-bind="value: StudentId" />
    
        </div>
        <div class="display-label">
            First Name
        </div>
        <div class="display-field">
            <input data-bind="value: FirstName" />
        </div>
    
        <div class="display-label">
            Last Name
        </div>
        <div class="display-field">
            <input data-bind="value: LastName" />
    
        </div>
    
        <div class="display-label">
            Age
        </div>
        <div class="display-field">
            <input data-bind="value: Age" />
    
        </div>
    
        <div class="display-label">
            Gender
        </div>
        <div class="display-field">
            <input data-bind="value: Gender" />
    
        </div>
    
        <div class="display-label">
            Batch
        </div>
        <div class="display-field">
            <input data-bind="value: Batch" />
    
        </div>
    
        <div class="display-label">
            Address
    
        </div>
        <div class="display-field">
            <input data-bind="value: Address" />
    
        </div>
    
        <div class="display-label">
            Class
        </div>
        <div class="display-field">
            <input data-bind="value: Class" />
    
        </div>
    
        <div class="display-label">
            School
        </div>
        <div class="display-field">
            <input data-bind="value: School" />
    
        </div>
    
        <div class="display-label">
            Domicile
        </div>
        <div class="display-field">
            <input data-bind="value: Domicile" />
    
        </div>
    </fieldset>
    
    <p>
        <button type="button" data-bind="click: DeleteStudent">Delete Student</button> |
        <a href="@Url.Action("Index", "Student")">Back to List</a>
    </p>
    
    @section Scripts {
        <script>
    
            $(function () {
                ko.applyBindings(DeleteVM);
            });
    
            var initialData = '@Html.Raw(ViewBag.InitialData)'; //get the raw json
            var parsedJSON = $.parseJSON(initialData); //parse the json client side
            var DeleteVM = {
                Domiciles: ko.observableArray(['Delhi', 'Outside Delhi']),
                Genders: ko.observableArray(['Male', 'Female']),
                Students: ko.observableArray([]),
                StudentId: ko.observable(parsedJSON.StudentId),
                FirstName: ko.observable(parsedJSON.FirstName),
                LastName: ko.observable(parsedJSON.LastName),
                Age: ko.observable(parsedJSON.Age),
                Batch: ko.observable(parsedJSON.Batch),
                Address: ko.observable(parsedJSON.Address),
                Class: ko.observable(parsedJSON.Class),
                School: ko.observable(parsedJSON.School),
                Domicile: ko.observable(parsedJSON.Domicile),
                Gender: ko.observable(parsedJSON.Gender),
                DeleteStudent: function () {
                    $.ajax({
                        url: '/Student/Delete',
                        type: 'post',
                        dataType: 'json',
                        data: ko.toJSON(this),
                        contentType: 'application/json',
                        success: function (result) {
                        },
                        error: function (err) {
                            if (err.responseText == "Creation Failed")
                            { window.location.href = '/Student/Index/'; }
                            else {
                                alert("Status:" + err.responseText);
                                window.location.href = '/Student/Index/';;
                            }
                        },
                        complete: function () {
                            window.location.href = '/Student/Index/';
                        }
                    });
                }
            };
    
        </script>
    }

    对于索引(显示列表)

    ViewModel

    var urlPath = window.location.pathname;
    $(function () {
        ko.applyBindings(StudentListVM);
        StudentListVM.getStudents();
    });
    
    //View Model
    var StudentListVM = {
        Students: ko.observableArray([]),
        getStudents: function () {
            var self = this;
            $.ajax({
                type: "GET",
                url: '/Student/FetchStudents',
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    self.Students(data); //Put the response in ObservableArray
                },
                error: function (err) {
                    alert(err.status + " : " + err.statusText);
                }
            });
        },
    };
    
    self.editStudent = function (student) {
        window.location.href =  '/Student/Edit/' + student.StudentId;
    };
    self.deleteStudent = function (student) {
        window.location.href = '/Student/Delete/' + student.StudentId;
    };
    
    //Model
    function Students(data) {
        this.StudentId = ko.observable(data.StudentId);
        this.FirstName = ko.observable(data.FirstName);
        this.LastName = ko.observable(data.LastName);
        this.Age = ko.observable(data.Age);
        this.Gender = ko.observable(data.Gender);
        this.Batch = ko.observable(data.Batch);
        this.Address = ko.observable(data.Address);
        this.Class = ko.observable(data.Class);
        this.School = ko.observable(data.School);
        this.Domicile = ko.observable(data.Domicile);
    }

    控制器方法

    public JsonResult FetchStudents()
            {
                return Json(db.Students.ToList(), JsonRequestBehavior.AllowGet);
            }

    视图

    @model IEnumerable<KnockoutWithMVC4.Student>
    
    @{
        ViewBag.Title = "Index";
    }
    
    <h2>Students List</h2>
    
    <p>
        <a href="@Url.Action("Create", "Student")" >Create Student</a>
    </p>
    <table>
        <thead>
            <tr>
                <th>
                    Student Id
                </th>
                <th>
                    First Name
                </th>
                <th>
                    Last Name
                </th>
                <th>
                    Age
                </th>
                <th>
                    Gender
                </th>
                <th>
                    Batch
                </th>
                <th>
                    Address
                </th>
                <th>
                    Class
                </th>
                <th>
                    School
                </th>
                <th>
                    Domicile
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody data-bind="foreach: Students">
            <tr>
                <td data-bind="text: StudentId"></td>
                <td data-bind="text: FirstName"></td>
                <td data-bind="text: LastName"></td>
                <td data-bind="text: Age"></td>
                <td data-bind="text: Gender"></td>
                <td data-bind="text: Batch"></td>
                <td data-bind="text: Address"></td>
                <td data-bind="text: Class"></td>
                <td data-bind="text: School"></td>
                <td data-bind="text: Domicile"></td>
                <td>
                    <a data-bind="click: editStudent">Edit</a>
                    <a data-bind="click: deleteStudent">Delete</a>
                </td>
            </tr>
        </tbody>
    </table>
    @section Scripts {
        @Scripts.Render("~/Scripts/ViewModels/StudentListVM.js")
    }

    return Json(db.Students.ToList(), JsonRequestBehavior.AllowGet); 代码以json格式返回学生对象,用于绑定到视图。

    现在一切就绪,您可以按F5运行应用程序,我们看到应用程序以与以前相同的方式运行,

     

    现在,您可以对该列表执行所有操作。 

     

     

    学生ID和年龄只能输入整数,因为缺少验证检查,可能会导致错误。

     

    现在创建新学生,

     

    我们看到学生已成功创建并添加到列表中,

     

    在数据库中,

     

    对于编辑也类似,

     

    更改任何字段并按保存。更改将反映在列表和数据库中,

     

    用于删除,

     

    学生已删除。

     

    在数据库中,

     

    十)Knockout属性词汇表  

    . observable:用于定义模型/实体属性。如果这些属性与用户界面绑定,并且当这些属性的值更新时,与这些属性绑定的UI元素将立即更新为新值。

    例如 this.StudentId = ko.observable("1"); - => StudentId 是可观察属性。KO 表示 Knockout.js 库的一个对象。

    可观察对象的值读取为var id= this. StudentId ();

     

    · observableArray: observableArray 代表需要通知的数据元素集合。它用于与列表类型的元素绑定。 

    例如 this.Students = ko.observableArray([]);

    · applyBindings:这用于激活当前HTML文档或HTML文档中特定UI元素的Knockout。此方法的参数是在JavaScript中定义的视图模型。此视图模型包含可观察对象、可观察数组和各种方法。

    本文使用了各种其他类型的绑定

    . click:表示添加到UI元素的点击事件处理程序,以便调用JavaScript函数。

    . value:这表示UI元素的值属性与ViewModel中定义的属性的值绑定。

    值绑定应与 <input><select><textarea> 一起使用

    . visible:这用于根据传递给其绑定的值来隐藏或取消隐藏UI元素。

    . Text:这表示传递给UI元素的参数的文本值。

    十一)结论

    在本系列文章“学习Knockout”中,我们学习了很多关于MVC、Entity Framework和Knockout.JS的知识。我们还通过创建一个CRUD操作应用程序进行了实践。

    因此,我们可以将其标记为已完成任务。

    我将在接下来的文章中介绍更多主题。

    注意:本文中的部分图片来自Google搜索。

    祝您编码愉快:).

© . All rights reserved.