自从到北京入职以来就再也没有接触MVC,很多都已经淡忘了,最近一直在看knockout.js 和webAPI,本来打算采用MVC+knockout.js+webAPI来实现这个小DEMO的,无奈公司用的开发环境是VS2010只安装了MVC3.0。那就先练习一下MVC和knockout吧。博客园里有很多这样的文章,但是觉得还是要自己亲自动手写一下。
本文不讲解knockout.js和webAPI ,不了解的同学可以百度一下。下一篇博文将采用webAPI和Redis缓存作为服务端重写该项目。
我们采用MVC和knockout.js实现一个简单的学生信息管理,实现学生信息的增删改查功能。通过knockout.js来进行数据的绑定,你会发现代码变得很优雅。在该项目中我们会用到razor视图以及Layout模板、RenderSection和Html.Partial等razor语法中的基本功能
项目需要添加knockout.js文件的引用,可以到官网上下载。
一、我们新建一个空的MVC项目
knockout.js在Script文件夹中,只用关注带黄色底纹的文件,其他没有用。
二、文件讲解
1、 我们先来看看_Layout.cshtml文件
_Layout.cshtml作为模板页面,Home文件夹下的所有*.cshtml都会引用该模板页,在_Layout.cshtml我们定义了@RenderSection("Header",false)一个区块,那么我们就可以在引用的具体页面中在该区域内添加css和js脚本了。@Html.Partial("FootPartialPage")说明我们引用了FootPartialPage. Cshtml的视图。
下面我们来看一下具体的代码
<!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/knockout-2.3.0.js")" type="text/javascript"></script> @RenderSection("Header",false) </head> <body> <div class="top"> </div> <div class="content"> @RenderBody() </div> <div class="foot"> @Html.Partial("FootPartialPage") </div> </body> </html>
2、Models/Students.cs
Students为我们定义的一个学生类的实体,作为数据的传递。
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MvcApplication1.Models { public class Students { public string Num { get; set; } public string Name { get; set; } public int Age { get; set; } public string Sex { get; set; } public string Class { get; set; } } }
3、 HomeController.cs控制器
HomeController中我们定义了很多Action,实现增删改查功能,直接看代码吧,Action中的代码最好配合着View来看。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication1.Models;
using System.Runtime.Serialization.Json;
using System.IO;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
private static List<Students> listStu = new List<Students>()
{
new Students(){Num="s0001",Name="张三",Age=19,Sex="man",Class="计算机1班"},
new Students(){Num="s0002",Name="李四",Age=20,Sex="man",Class="计算机1班"},
new Students(){Num="s0003",Name="王五",Age=18,Sex="man",Class="计算机1班"},
new Students(){Num="s0004",Name="小红",Age=17,Sex="women",Class="计算机'\"1班"},
};
//首页
public ActionResult Index()
{
//序列化为json数据
DataContractJsonSerializer Serializer = new DataContractJsonSerializer(typeof(List<Students>));
using (MemoryStream ms = new MemoryStream())
{
Serializer.WriteObject(ms,listStu);
ms.Flush();
ms.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(ms);
ViewBag.Data = sr.ReadToEnd();
}
return View(ViewBag);
}
//新增页面
public ActionResult Add()
{
return View();
}
//新增事件
[HttpPost]
public JsonResult Add(FormCollection form)
{
listStu.Add(
new Students() { Num = form["Num"], Name = form["Name"], Age = Convert.ToInt32(form["Age"]), Sex = form["Sex"], Class = form["Class"] }
);
return Json(new { type = "success" });
}
//编辑页面
public ActionResult edit(string id)
{
var item = listStu.Find(it => it.Num == id);
//序列化为json数据
DataContractJsonSerializer Serializer = new DataContractJsonSerializer(typeof(Students));
using (MemoryStream ms = new MemoryStream())
{
Serializer.WriteObject(ms, item);
ms.Flush();
ms.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(ms);
ViewBag.Data = sr.ReadToEnd();
}
return View("eidt");
}
//编辑事件
[HttpPost]
public JsonResult edit(FormCollection form)
{
string Num = form["Num"];
var item = listStu.Find(it => it.Num == Num);
item. Name = form["Name"];
item. Age = Convert.ToInt32(form["Age"]);
item. Sex = form["Sex"];
item. Class = form["Class"];
return Json(new { type = "success" });
}
//删除
[HttpPost]
public JsonResult Del(string id)
{
var item = listStu.Find(it => it.Num == id);
listStu.Remove(item);
return Json(new { type = "sucess" });
}
}
}
4、 Index.cshtml视图
Index.cshtm是我们的首页,接收一个@ViewBag.Data的jason数据(该json数据是list<student>序列化来的,查看源代码就可以看到该数据),通过knockout.js把数据绑定到页面中。代码如下:
@{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } @section Header{ <script type="text/javascript"> var data =@Html.Raw(@ViewBag.Data); function ViewModel(){ var self=this; self.students=ko.observableArray(data);//添加动态监视数组对象 //删除 self.remove=function(stu){ $.ajax({ url:"/Home/Del/"+stu.Num, type:"post", dataType:"json", success:function(json){ alert(json.type); self.students.remove(stu); } }) } //编辑 self.edit=function(stu){ window.location.href='/Home/edit/'+stu.Num; }; self.Count=ko.computed(function(){ return self.students().length; }); } $(document).ready(function(){ var vm=new ViewModel(); /* 新增元素 var obj=new Object(); obj.Num='s0002'; obj.Name='eric'; obj.Age='25'; obj.Sex='男'; obj.Class='计算机2班'; vm.students.push(obj); */ ko.applyBindings(vm); }) </script> } <div style=" margin-bottom:5px;"> <a href="/Home/Add/">增加</a> </div> <table cellpadding="1" cellspacing="1" border="1" width="100%"> <tr> <th style="width:auto">姓名</th> <th style="width:auto">年龄</th> <th style="width:auto">性别</th> <th style="width:auto">班级</th> <th style="width:auto">操作</th> </tr> <tbody data-bind="foreach:students"> <tr> <td data-bind="text:Name"></td> <td data-bind="text:Age"></td> <td data-bind="text:Sex"></td> <td data-bind="text:Class"></td> <td > <a href="javascript:" data-bind="click:$root.remove">删除</a> <a href="javascript:" data-bind="click:$root.edit">修改</a></td> </tr> </tbody> </table> <div data-bind="text:Count"></div>
5、 eidt.cshtml视图
eidt.cshtml是编辑学生信息的页面,与Index.cshtm页面类似,该页面也是接收一个json数据,并通过knockout.js把数据绑定到页面中
@{ ViewBag.Title = "eidt"; Layout = "~/Views/Shared/_Layout.cshtml"; } @section Header{ <script type="text/javascript"> var data =@Html.Raw(@ViewBag.Data); function ViewModel(){ var self=this; self.Num=ko.observable(data.Num); self.Name=ko.observable(data.Name); self.Age=ko.observable(data.Age); self.Sex=ko.observable(data.Sex); self.Class=ko.observable(data.Class); self.Commit1=function(){ //alert(self.Num()+","+self.Name()+","+self.Age()+","+self.Sex()+","+self.Class()); $.ajax({ type:"post", url:"/Home/edit", data:{Num:self.Num(),Name:self.Name,Age:self.Age,Sex:self.Sex,Class:self.Class}, success:function(json){ alert(json.type); } }) } self.back=function(){ window.location.href='/Home/Index'; }; } $(document).ready(function(){ var vm=new ViewModel(); ko.applyBindings(vm); }) </script> } <h2>eidt</h2> <table cellpadding="1" cellspacing="1" border="1" width="100%"> <tr> <td style="width:100px">姓名:</td> <td><input type="text" data-bind="value:Name" /></td> </tr> <tr> <td style="width:100px">年龄:</td> <td><input type="text" data-bind="value:Age" /></td> </tr> <tr> <td style="width:100px">性别:</td> <td><input type="text" data-bind="value:Sex" /></td> </tr> <tr> <td style="width:100px">班级:</td> <td><input type="text" data-bind="value:Class" /></td> </tr> </table> <div style=" margin-top:5px"> <input type="button" data-bind="click:$root.Commit1" value="提交"/> <input type="button" data-bind="click:$root.back" value="返回"/> </div>
6、 Add.cshtml 视图
Add.cshtml是添加用户信息的页面与eidt.cshtml页面非常类似,直接上代码
@{
ViewBag.Title = "Add";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@section Header{
<script type="text/javascript">
function ViewModel(){
var self=this;
self.Num=ko.observable();
self.Name=ko.observable();
self.Age=ko.observable();
self.Sex=ko.observable();
self.Class=ko.observable();
self.Commit1 = function () {
$.ajax({
type: "post",
url: "/Home/Add",
data: { Num: self.Num(), Name: self.Name(), Age: self.Age(), Sex: self.Sex, Class: self.Class },
success: function (json) {
alert(json.type);
}
})
}
self.back=function(){
window.location.href='/Home/Index';
};
}
$(document).ready(function(){
var vm=new ViewModel();
ko.applyBindings(vm);
})
</script>
}
<h2>Add</h2>
<table cellpadding="1" cellspacing="1" border="1" width="100%">
<tr>
<td style="width:100px">学号:</td>
<td><input type="text" data-bind="value:Num" /></td>
</tr>
<tr>
<td style="width:100px">姓名:</td>
<td><input type="text" data-bind="value:Name" /></td>
</tr>
<tr>
<td style="width:100px">年龄:</td>
<td><input type="text" data-bind="value:Age" /></td>
</tr>
<tr>
<td style="width:100px">性别:</td>
<td><input type="text" data-bind="value:Sex" /></td>
</tr>
<tr>
<td style="width:100px">班级:</td>
<td><input type="text" data-bind="value:Class" /></td>
</tr>
</table>
<div style=" margin-top:5px">
<input type="button" data-bind="click:$root.Commit1" value="提交"/>
<input type="button" data-bind="click:$root.back" value="返回"/>
</div>
到此该列子已经讲解完毕,点击此处下载源代码。
下一章中我们采用webAPI作为服务来实现该列子。
每天学习一点点,每天进步一点点。