Knockout是一个轻量级的UI类库,通过应用MVVM模式使JavaScript前端UI简单化。
Knockout是一个以数据模型(data model)为基础的能够帮助你创建富文本,响应显示和编辑用户界面的JavaScript类库。任何时候如果你的UI需要自动更新(比如:更新依赖于用户的行为或者外部数据源的改变),KO能够很简单的帮你实现并且很容易维护。
Knockout有如下4大重要概念:
1、声明式绑定 (Declarative Bindings):使用简明易读的语法很容易地将模型(model)数据关联到DOM元素上。
2、UI界面自动刷新 (Automatic UI Refresh):当您的模型状态(model state)改变时,您的UI界面将自动更新。
3、依赖跟踪 (Dependency Tracking):为转变和联合数据,在你的模型数据之间隐式建立关系。
4、模板 (Templating):为您的模型数据快速编写复杂的可嵌套的UI。
简称:KO
1、 创建不带有监控属性的ViewModel
创建一个view model,只需要声明任意的JavaScript object。例如:
var myViewModel = { personName: 'Bob', personAge: 123 };
把该ViewModel绑定到HTMl代码中,例如:下面的代码显示personName 值
The name is <span data-bind="text: personName"></span>
激活Knockout,需要添加如下的 <script> 代码块:
ko.applyBindings(myViewModel);
2、创建带有监控属性的view model
监控属性Observables
现在已经知道如何创建一个简单的view model并且通过binding显示它的属性了。但是KO一个重要的功能是当你的view model改变的时候能自动更新你的界面。当你的view model部分改变的时候KO是如何知道的呢?答案是:你需要将你的model属性声明成observable的, 因为它是非常特殊的JavaScript objects,能够通知订阅者它的改变以及自动探测到相关的依赖。
例如:将上述例子的view model改成如下代码:
var myViewModel = { personName: ko.observable('Bob'), personAge: ko.observable(123) };
你根本不需要修改view – 所有的data-bind语法依然工作,不同的是他能监控到变化,当值改变时,view会自动更新。
在我们的系统中,每一个页面都会定义一个ViewModel,该ViewModel存储页面所有的数据,并通过ajax读取数据并填写ViewModel。
假如我们有一个班级的页面,定义如下一个ViewModel:
//定义视图 var ClassViewModel = { ClassID:ko.observable(),//班级ID ClassName: ko.observable(),//班级名称 ClassMasterName: ko.observable(),//班主任 Students: ko.observableArray(),//班级学生列表 绑定数组 }; $(document).ready(function () { //绑定 ko.applyBindings(ClassViewModel); //添加学生信息 $("#AddStudent").on("click", function () { var obj = new Object(); obj.StuName = "杨过"; obj.StuSex = "猛男"; obj.StuAge = "100"; ClassViewModel.Students.push(obj); }); }); //ajax获取班级信息,并给ViewModel赋值 $.post("/home/GetClassInfo", function (data) { ClassViewModel.ClassID(data.ClassID);//班级ID赋值,会直接映射到界面 ClassViewModel.ClassName(data.ClassName); ClassViewModel.ClassMasterName(data.ClassMasterName); //获取学生信息 for (var i = 0; i < data.StuList.length; i++) { var obj = new Object(); obj.StuName=data.StuList[i].StuName; obj.StuSex=data.StuList[i].StuSex; obj.StuAge = data.StuList[i].StuAge; ClassViewModel.Students.push(obj); } })
对应的Html代码:
<script src="~/Scripts/jquery-1.7.1.min.js"></script> <script src="~/Scripts/knockout-3.2.0.js"></script> <script src="~/Scripts/ViewModel/MyClassViewModel.js"></script> <h2>MyClass</h2> <!-- attr属性绑定 --> 班级名称:<span data-bind="text:ClassID,attr:{'ID':ClassID}"></span><br/> 班主任:<span data-bind="text:ClassName"></span><br/> <table> <tr> <th> 名字 </th> <th> 性别 </th> <th> 年龄 </th> </tr> <!--循环绑定 Students --> <tbody data-bind="foreach:Students"> <tr> <td data-bind="text:StuName"> </td> <td data-bind="text:StuSex"> </td> <td data-bind="text:StuAge"> </td> </tr> </tbody> </table> <br/> <input type="button" id="AddStudent" value="添加学生" />
后台数据:
public class HomeController : Controller { public ActionResult Index() { ViewBag.Message = "修改此模板以快速启动你的 ASP.NET MVC 应用程序。"; return View(); } public ActionResult About() { ViewBag.Message = "你的应用程序说明页。"; return View(); } public ActionResult Contact() { ViewBag.Message = "你的联系方式页。"; return View(); } public ActionResult MyClass() { return View(); } public JsonResult GetClassInfo() { MyClass myClass = new MyClass(); myClass.ClassID = "jsj001"; myClass.ClassName = "计算机一班"; myClass.ClassMasterName = "龙龙"; myClass.StuList = new List<Students>(); myClass.StuList.Add(new Students() { StuAge = "10", StuName = "张三", StuSex = "暖男" }); myClass.StuList.Add(new Students() { StuAge = "20", StuName = "李四", StuSex = "暖男" }); myClass.StuList.Add(new Students() { StuAge = "30", StuName = "王五", StuSex = "暖男" }); return Json(myClass); } } public class MyClass { /// <summary> /// 班级ID /// </summary> public string ClassID { get; set; } /// <summary> /// 班级名称 /// </summary> public string ClassName { get; set; } /// <summary> /// 班主任名称 /// </summary> public string ClassMasterName { get; set; } public List<Students> StuList { get; set; } } public class Students { public string StuName { get; set; } public string StuSex { get; set; } public string StuAge { get; set; } }