bob体育官方平台
【Knockout.js 学习体验之旅】(1)ko初体验

MVVM框架中Angular是好,但这么大而全的框架,学习难度可不低呢,上手起码也得要个一两周吧。而knockoutjs专注于数据绑定,只需一两天就可以投入使用了,学习成本不要太低!在前端进化如此迅速的时代,学习成本也是不得不考虑的一个因素。很多时候其实我们的项目并没那么复杂,也并不需要万能的框架,更需要的反而是简单顺手的工具。

前言

KnockoutJs快速入门教程,knockoutjs入门教程

一、引言

之前这个系列文章已经介绍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: </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: </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>

关于模板更多的使用参考官方文档:

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

一、引言 之前这个系列文章已经介绍Bootstrap,详情请查看本文: 《Bootstrap入门教程》 ,由于最近...

Before Knockoutjs

什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular、React啊,再不赶紧的话,他们也要变out了哦。身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包,却依然振振有词地喋喋不休,一脸真诚。是啊,前端发展太快,那边前几年出的框架已是无人问津的半老徐娘,而这边各种新出的框架却正在风口搔首弄姿,娇翠欲滴。前端界好不热闹!当然,楼主也喜欢新奇趣,但是现在公司的开发工具(WeX5)中用到了knockout.js,没办法,再老都只能蒙着眼睛上了……

假设我们做一个订单系统,需要显示商品单价,然后可以根据输入数量计算出总价并显示出来。使用原生代码也很容易实现,效果:

然后发现,咦!感觉还不错呀~~~

Price: 
Account: 
sum:  //js codevar priceNode = document.getElementById,accountNode = document.getElementById,sumNode = document.getElementById,price = 100,account = 11,sum = price * account;//初始化。priceNode.innerText = price;accountNode.value = account;sumNode.textContent = sum;//监视 View层的用户输入accountNode.addEventListener('keydown', function  {window.setTimeout {account = accountNode.value;sum = price * account;sumNode.textContent = sum;},10);}); 

图片 1

嗯,蛮简单的!哦,对了,我们一次展示50件商品,同时又有10类这样的展示,还有买5盒冈本送一根油条这样的各种促销……

MVVM框架中Angular是好,但这么大而全的框架,学习难度可不低呢,上手起码也得要个一两周吧。而knockout.js专注于数据绑定,只需一两天就可以投入使用了,学习成本不要太低!在前端进化如此迅速的时代,学习成本也是不得不考虑的一个因素。很多时候其实我们的项目并没那么复杂,也并不需要万能的框架,更需要的反而是简单顺手的工具。

返回顶部