自從到北京入職以來就再也沒有接觸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" });
}
}
}
View Code
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 [email protected](@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 [email protected](@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作為服務來實作該列子。
每天學習一點點,每天進步一點點。