一、引言

  之前这个系列文章已经介绍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. Sanarus公司的Cassi微创乳房活检设备投入使用

    这种新型可转动的大核心乳房活检设备,是一种全自动一次性的手工操作的设备.该设备对乳房造成的创伤最小,是传统乳房活检设备很好的替代选择. 该设备被称作Cassi,操作方便而且无需准备时间.无需固定设备的 ...

  2. 16条Web2.0法则的编程思想

    1.在你开始之前,先定一个简单的目标.无论你是一个Web 2.0应用的创建者还是用户,请清晰的构思你的目标.就像“我需要保存一个书签”或者“我准 备帮助人们创建可编辑的.共享的页面”这样的目标,让你保 ...

  3. vue2 上传图片

    <template> <div class="vue-upload-img-multiple"> <div v-if="images.len ...

  4. 【转载】Java中的回车换行符/n /r /t

    source:http://hane00.blog.163.com/blog/static/1600615220126204446809/ '\r'是回车,'\n'是换行,前者使光标到行首,后者使光标 ...

  5. log4j向oracle中插入一条系统当前时间的sql语句

    配置log4j,要向oracle插入一条系统当前时间的sql语句,按网上查找的总是出现各种各样的报错,最后总结出的写法是: ### shezhi### log4j.rootLogger = debug ...

  6. spring in action 第五章基于注解搭建SpringMvc环境

    request的生命历程

  7. home键通知

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("closeAlert"), n ...

  8. tomee 消息持久化

    http://tomee.apache.org/jms-resources-and-mdb-container.html http://activemq.apache.org/xml-configur ...

  9. IIS支持解析json

      IIS支持解析json 一. windows XP   1. MIME设置: 在IIS的站点属性的HTTP头设置里,选MIME 映射中点击"文件类型"-"新类型&qu ...

  10. WPF 图片显示中的保留字符问题

    在WPF中显示一张图片,本是一件再简单不过的事情.一张图片,一行XAML代码即可. 但是前段时间遇到了一件奇怪的事: 开发机上运行正常的程序,在某些客户机器上却显示不了图片,而且除了这个问题,其它运行 ...