一、引言

  之前这个系列文章已经介绍Bootstrap。由于最近项目中,前端是Asp.net MVC + KnockoutJs + Bootstrap来做的。所以我又重新开始写这个系列。今天就让我们来看看Web前端的MVVM框架——KnockoutJs。

二、KnockoutJs是什么?

  做.NET开发的人应该都知道,WPF中就集成了MVVM框架,关于WPF系列可以参考我WPF系列:http://www.cnblogs.com/zhili/category/624221.html。所以KnockoutJs也是针对Web开发的MVVM框架。关于MVVM好处简单点来说就是——使得业务逻辑代码与页面展示代码分割开,使得前端项目更好维护。

  之前,我们写Web页面的时候,JS代码和Html代码混合在一起,并且代码中充斥着大量的DOM对象的操作。这样代码结构非常混乱。有了MVVM框架了,你可以将JS代码和Html代码分割开,并且数据操作部分更加简单,只需要通过相应的语法(data-bind)绑定到对应的标签属性显示即可,从而加快开发速度。

  KnockoutJs也就是这样一个MVVM框架。其实与其称其框架,更准备地应该是一个MVVM类库。因为它没有MVVM框架是一个比较“重”的概念,其中应该包括路由等特性。而KnockoutJS中却没有,相比较,AngularJS应该称为一个MVVM框架更加合适。

  KnockoutJS主要实现的功能有以下4点:

  • 声明式绑定(Declarative Bindings):使用简单的语法将模型数据关联到DOM元素上。即"data-bind"语法
  • 依赖跟踪(Dependency Tracking):为转变和联合数据,在模型数据之间建立关系。如商品总价是由各个商品项价格之和。此时商品总价和商品项就可以使用依赖跟踪功能来建立关系。即由各个商品项的总价相加而得出。这种关系由KnockoutJs中computed函数完成。
  • UI界面自动刷新(Automatic UI Refresh):当你的模型状态改变时,UI界面的将自动更新。这点由observable函数完成。
  • 模板(Templating):为您的模型数据快速编写复杂的可嵌套UI。和WPF中模板的概念类似。

  接下来,我们通过具体的例子来让大家快速掌握KnockoutJs的使用。

三、声明式绑定

  下面让我们看下如何使用KnockoutJS中的data-bind语法来将模型数据绑定到DOM元素中。

  1. 单向绑定
<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Demo1-单向绑定</title>
<script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/376/pbcx3e1z/knockout-3.4.0.js"></script>
</head>
<body>
<!--单向绑定-->
<div>
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>
</div> <!--这段脚本实际项目中应该放在对应的JS文件中,然后在html中通过Script标签来引用即可-->
<!--JS代码也就是业务逻辑部分,将业务逻辑与Html代码分割开,使得View代码更加简洁,这样后期也易于维护-->
<script type="text/javascript">
function ViewModel() {
this.firstName = "Tommy";
this.lastName = "Li";
}
ko.applyBindings(new ViewModel());
</script>
</body>
</html>

  在线演示地址:http://sandbox.runjs.cn/show/4nruobca

  2. 上面的例子只是完成了单向绑定的操作。即在上面的例子你会发现,当改变input标签中的值并离开焦点时,上面的值不会更新。其实,KnockoutJS中自动更新功能不会自动添加的,需要对应的函数支持,这个函数就是observable函数,下面具体看看双向绑定的例子:

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Demo2-双向绑定</title> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/376/pbcx3e1z/knockout-3.4.0.js"></script>
</head>
<body>
<!--双向绑定-->
<div>
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<p>First name: <input data-bind="value: firstName"/></p>
<p>Last name: <input data-bind="value: lastName" /></p>
</div> <script type="text/javascript">
function ViewModel() {
this.firstName = ko.observable("Tommy");
this.lastName = ko.observable("Li");
} ko.applyBindings(new ViewModel());
</script>
</body>
</html>

  在线预览地址:http://sandbox.runjs.cn/show/oe58jbs3

四、依赖跟踪

  接下来让我们看下如何使用KO中的computed函数来完成依赖跟踪。具体例子的实现代码如下所示:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Demo3-依赖跟踪</title> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/376/pbcx3e1z/knockout-3.4.0.js"></script>
</head>
<body>
<!--双向绑定-->
<div>
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName"/></p>
<p>Full name: <strong data-bind="text: fullName"></strong></p>
<button data-bind="click: capitalizeLastName">LastName To Upper</button>
</div> <script type="text/javascript">
function ViewModel() {
this.firstName = ko.observable("Tommy");
this.lastName = ko.observable("Li");
// 依赖跟踪
this.fullName = ko.computed(function () {
return this.firstName() + " " + this.lastName();
},this); // 通过代码改变observable的值
this.capitalizeLastName = function() {
this.lastName(this.lastName().toUpperCase());
};
} ko.applyBindings(new ViewModel());
</script>
</body>
</html>

  在线预览地址:http://sandbox.runjs.cn/show/t8yokfel

 接下来,让我们看一下使用声明式绑定和依赖跟踪复杂点的例子。具体示例代码如下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Demo4-列表绑定</title> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/376/pbcx3e1z/knockout-3.4.0.js"></script>
</head>
<body>
<table>
<thead>
<tr>
<td>Name</td>
<td>Amount</td>
<td>Price</td>
</tr>
</thead>
<tbody data-bind="foreach: items">
<tr>
<td data-bind="text: product.name"></td>
<td><select data-bind="options:[1,2,3,4,5,6],value: amount"></select></td>
<td data-bind="text: subTotal"></td>
<td><a href="#" data-bind="click: $root.remove">Remove</a></td>
</tr>
</tbody>
</table>
<h3>Order Price: <span data-bind="text: price"></span></h3>
<button data-bind="click: addComputer">Add a Computer</button> <script type="text/javascript">
var products = [{ name: "Learnighard 学习笔记", price: 49 },
{ name: "小米Note", price: 999 },
{ name: "宏碁笔记本", price: 4999 }]; // 订单类
function Order() {
var self = this;
this.items = ko.observableArray([
new Item(products[0], 1),
new Item(products[1],2)
]);
// 订单总价
this.price = ko.computed(function() {
var p = 0;
for (var i = 0; i < self.items().length; i++) {
var item = self.items()[i];
p += item.product.price * item.amount();
}
return p;
}, self); this.remove = function(item) {
self.items.remove(item);
}; this.addComputer = function () {
self.items.push(new Item(products[2], 1));
};
} // 订单项类
function Item(product, amount) {
var self = this;
this.product = product;
this.amount = ko.observable(amount);
// 订单项总价
this.subTotal = ko.computed(function() {
return self.amount() * self.product.price;
}, self);
} ko.applyBindings(new Order());
</script>
</body>
</html>

  在线预览地址为:http://sandbox.runjs.cn/show/109jsjvz

五、模板

  看完以上几个例子,其实你应该感觉到KO(KnockoutJS的简称)的上手还是非常简单的。因为其语法都非常容易理解,接下来看下KO中模板的使用。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Demo5-模板绑定</title> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/376/pbcx3e1z/knockout-3.4.0.js"></script>
</head>
<body>
<!--模板绑定,div的内容为personTemplate模板内的标签-->
<!--即最终生成如下标签-->
<!--<div>
<p>Name: <strong data-bind="text: name"></strong></p>
<p>Age: <strong data-bind="text: age"></strong></p>
</div>-->
<div data-bind="template:'personTemplate'"></div> <script id="personTemplate" type="text/html">
<p>Name: <strong data-bind="text: name"></strong></p>
<p>Age: <strong data-bind="text: age"></strong></p>
</script> <script type="text/javascript">
var ViewModel = {
name: ko.observable('Tommy'),
age: ko.observable(28),
makeOlder: function() {
this.age(this.age() + 1);
}
}; ko.applyBindings(ViewModel);
</script>
</body>
</html>

  在线预览地址为:http://sandbox.runjs.cn/show/3fnpkvrs

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Demo6-模板绑定</title> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/376/pbcx3e1z/knockout-3.4.0.js"></script>
</head>
<body>
<h2>Participants</h2>
Here are the participants:
<div data-bind="template: { name: 'persontemplate', foreach: people }"></div> <script type="text/html" id="persontemplate">
<h3 data-bind="text: name"></h3>
<p>Age: <span data-bind="text: age"></span></p>
</script>
<script type="text/javascript">
function MyViewModel() {
this.people = [
{ name: 'Tommy', age: 27 },
{ name: 'Frank', age: 33 }
];
}
ko.applyBindings(new MyViewModel());
</script>
</body>
</html>

  在线预览地址为:http://sandbox.runjs.cn/show/kujxhfgv

  关于模板更多的使用参考官方文档:http://knockoutjs.com/documentation/template-binding.html。本文只列出了2中模板的使用。

六、总结

  到此,KnockoutJs的快速入门的内容就结束了,在一篇文章中继续为大家介绍KO内容,下一篇文章的内容将介绍如何使用KO来做一个实际的项目。

  本文所有源码下载地址:https://code.msdn.microsoft.com/KnockoutJs-d9472ff9

[后端人员耍前端系列]KnockoutJs篇:快速掌握KnockoutJs的更多相关文章

  1. [后端人员耍前端系列]AngularJs篇:30分钟快速掌握AngularJs

    一.前言 对于前端系列,自然少不了AngularJs的介绍了.在前面文章中,我们介绍了如何使用KnockoutJs来打造一个单页面程序,后面一篇文章将介绍如何使用AngularJs的开发一个单页面应用 ...

  2. [后端人员耍前端系列]Bootstrap篇:30分钟快速掌握Bootstrap

    一.引言 很久没有写过博客了,但是最近这段时间都没有闲着,接触了很多方面.比如一些前端框架和组件.还有移动开发React-Native.以及对.NET框架设计的一些重新认识.这些内容在接下来的时间都会 ...

  3. [后端人员耍前端系列]AngularJs篇:使用AngularJs打造一个简易权限系统

    一.引言 上一篇博文已经向大家介绍了AngularJS核心的一些知识点,在这篇博文将介绍如何把AngularJs应用到实际项目中.本篇博文将使用AngularJS来打造一个简易的权限管理系统.下面不多 ...

  4. [后端人员耍前端系列]KnockoutJs篇:使用WebApi+Bootstrap+KnockoutJs打造单页面程序

    一.前言 在前一个专题快速介绍了KnockoutJs相关知识点,也写了一些简单例子,希望通过这些例子大家可以快速入门KnockoutJs.为了让大家可以清楚地看到KnockoutJs在实际项目中的应用 ...

  5. [后端人员耍前端系列]KnockoutJs篇:使用KnockoutJs+Bootstrap实现分页

    一.引言 由于最近公司的系统需要改版,改版的新系统我打算使用KnockoutJs来制作Web前端.在做的过程中,遇到一个问题——如何使用KnockoutJs来完成分页的功能.在前一篇文章中并没有介绍使 ...

  6. [Vue 牛刀小试]:第十六章 - 针对传统后端开发人员的前端项目框架搭建

    一.前言 在之前学习 Vue 基础知识点的文章中,我们还是采用传统的方式,通过在 html 页面上引用 vue.js 这个文件,从而将 Vue 引入到我们的项目开发中.伴随着 Node.js 的出现, ...

  7. 旨在脱离后端环境的前端开发套件 - IDT Server篇

    IDT,一个基于Nodejs的,旨在脱离后端环境的前端开发套件,目的就是能让前端开发完全脱离后端的环境,无论后端是什么模板引擎(主流),都能应付自如. IDT主要包括两大部分:Server + Bui ...

  8. 旨在脱离后端环境的前端开发套件 - IDT之Server篇

    IDT,一个基于Nodejs的,旨在脱离后端环境的前端开发套件,目的就是能让前端开发完全脱离后端的环境,无论后端是什么模板引擎(主流),都能应付自如. IDT主要包括两大部分:Server + Bui ...

  9. 前端工程师技能之photoshop巧用系列第二篇——测量篇

    × 目录 [1]测量信息 [2]实战 [3]注意事项 前面的话 前端工程师使用photoshop进行的大量工作实际上是测量.本文是photoshop巧用系列第二篇——测量篇 测量信息 在网页制作中需要 ...

随机推荐

  1. POJ 3041 Asteroids 二分图匹配

    以行列为点建图,每个点(x,y) 对应一条边连接x,y.二分图的最小点覆盖=最大匹配 //#pragma comment(linker, "/STACK:1024000000,1024000 ...

  2. 史上最强防火墙iptables

    #1.清空所有的防火墙规则 iptables -F iptables -X iptables -Z iptables -t NAT -F iptables -t NAT -X iptables -t ...

  3. C、C++、Java、go的语法区别

    详细C++.Java比较:http://www.cnblogs.com/stephen-liu74/archive/2011/07/27/2118660.html 一.C.C++的区别 在很大程度上, ...

  4. windows读取mac格式移动硬盘的方法

    本文记录了一些window与mac数据在移动设备上互相拷贝的经验. 一.准备 家里有一台mac电脑,限于硬盘空间比较小,需要定期备份一些数据. 由于备份数据大小在20G左右,并且并没有压缩为一个压缩文 ...

  5. 使用 KGDB 调试 Kernel On Red Hat Linux

    1. KGDB 简介         KGDB  提供了一种使用 GDB 调试 Linux 内核的机制.使用 KGDB 可以象调试普通的应用程序那样,在内核中进行设置断点.检查变量值.单步跟踪程序运行 ...

  6. android源码环境下用mmm/mm编译模块,输出编译log到文件的方法

    android源码环境下用mmm/mm编译模块,输出编译log到文件的方法 1,在android目录下直接用mmm命令编译, log信息保存在android目录下 mmm packages/apps/ ...

  7. 如何使用ajax将json传入后台数据

    首先采用jquery内部封装好的方法是比较简单的,我们只需做的就是修改里面的一些配置: 对$.ajax()的解析: $.ajax({ type: "POST", //提交方式 co ...

  8. LInux javac时, 提示command not found

    这个是我之前看了很多的论坛发现的问题,我想了很久也没有发现问题,明明路径都是对的,配置文件也没有错误,为什么最后却只有执行java好使,但是执行javac不好使 因为java分两个版本一个是jre,一 ...

  9. 启动tomcat时遇到的问题

    1.当启动Tomcat时,出现了如下信息: The APR based Apache Tomcat Native library which allows optimal performance in ...

  10. 使用Notepad++作为IDE代替Source Insight

    视图-->Folder as Workspace 视图-->函数列表 设置-->语言格式设置-->选择主题 插件-->Plugin Manager-->装上NppG ...