KnockoutJs快速入门教程


Posted in Javascript onMay 16, 2016

一、引言

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

二、KnockoutJs是什么?

做.NET开发的人应该都知道,WPF中就集成了MVVM框架,所以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="/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>

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

<!DOCTYPE html>

<html>
<head>
 <meta name="viewport" content="width=device-width" />
 <title>Demo2-双向绑定</title>
 
 <script type="text/javascript" src="/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>

四、依赖跟踪
接下来让我们看下如何使用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="/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>

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

<!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>

五、模板
看完以上几个例子,其实你应该感觉到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="/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>
<!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://knockoutjs.com/documentation/template-binding.html。本文只列出了2中模板的使用。

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

Javascript 相关文章推荐
javascript Keycode对照表
Oct 24 Javascript
JSON 数字排序多字段排序介绍
Sep 18 Javascript
在 Express 中使用模板引擎
Dec 10 Javascript
jQuery+CSS实现滑动的标签分栏切换效果
Dec 17 Javascript
微信JSAPI Ticket接口签名详解
Jun 28 Javascript
javascript简写常用的12个技巧(可以大大减少你的js代码量)
Mar 28 Javascript
JavaScript中发出HTTP请求最常用的方法
Jul 12 Javascript
浅谈ElementUI中switch回调函数change的参数问题
Aug 24 Javascript
VUE中使用MUI方法
Feb 12 Javascript
了解在JavaScript中将值转换为字符串的5种方法
Jun 06 Javascript
jquery.pager.js分页实现详解
Jul 29 jQuery
Vue常用传值方式、父传子、子传父及非父子实例分析
Feb 24 Javascript
JS学习之表格的排序简单实例
May 16 #Javascript
JavaScript操作选择对象的简单实例
May 16 #Javascript
JS组件Bootstrap实现图片轮播效果
May 16 #Javascript
Bootstrap4一次重大更新 几乎涉及每行代码
May 16 #Javascript
JS获取元素多层嵌套思路详解
May 16 #Javascript
怎么限制input的text里输入的值只能是数字(正则、js)
May 16 #Javascript
BootStrap点击下拉菜单项后显示一个新的输入框实现代码
May 16 #Javascript
You might like
PHP PDOStatement对象bindpram()、bindvalue()和bindcolumn之间的区别
2014/11/20 PHP
微信支付之JSAPI公众号支付详解
2019/05/15 PHP
Laravel定时任务的每秒执行代码
2019/10/22 PHP
来自国外的14个图片放大编辑的jQuery插件整理
2010/10/20 Javascript
jQuery lazyload 的重复加载错误以及修复方法
2010/11/19 Javascript
原生javascript获取元素样式属性值的方法
2010/12/25 Javascript
通过js动态操作table(新增,删除相关列信息)
2012/05/23 Javascript
封装好的一个万能检测表单的方法
2015/01/21 Javascript
Javascript 正则表达式实现为数字添加千位分隔符
2015/03/10 Javascript
js实现字符串和数组之间相互转换操作
2016/01/12 Javascript
JavaScript对象数组如何按指定属性和排序方向进行排序
2016/06/15 Javascript
AngularJS 简单应用实例
2016/07/28 Javascript
Three.js获取鼠标点击的三维坐标示例代码
2017/03/24 Javascript
JS实现的简单下拉框联动功能示例
2018/05/11 Javascript
Vue组件创建和传值的方法
2018/08/17 Javascript
详解react阻止无效重渲染的多种方式
2018/12/11 Javascript
js+springMVC 提交数组数据到后台的实例
2019/09/21 Javascript
Python使用metaclass实现Singleton模式的方法
2015/05/05 Python
python编程实现归并排序
2017/04/14 Python
python3实现随机数
2018/06/25 Python
Python中矩阵创建和矩阵运算方法
2018/08/04 Python
结合OpenCV与TensorFlow进行人脸识别的实现
2019/10/10 Python
python 爬虫网页登陆的简单实现
2020/11/30 Python
python不同版本的_new_不同点总结
2020/12/09 Python
详解python第三方库的安装、PyInstaller库、random库
2021/03/03 Python
html5与css3小应用
2013/04/03 HTML / CSS
京东全球售:直邮香港,澳门,台湾,美国,澳大利亚等地区
2017/09/24 全球购物
英国男士时尚网站:Dandy Fellow
2018/02/09 全球购物
DJI大疆德国官方商城:大疆无人机
2018/09/01 全球购物
Bailey帽子官方商店:Bailey Hats
2018/09/25 全球购物
大学生简历的个人自我评价
2013/12/04 职场文书
正规的求职信范文分享
2013/12/11 职场文书
经理秘书找工作求职信
2013/12/19 职场文书
2014年工程师工作总结
2014/11/25 职场文书
团拜会主持词
2015/07/04 职场文书
新闻稿标题
2015/07/18 职场文书