iT邦幫忙

8

{'JS-Objects':2} Knockout.js入門(1)

之前曾過寫稍微寫過Flex,對於它在資料和元件之間的data binding設計,印象非常深刻。它既能從UI元件上更動,去變更資料,也能在資料變更時,即時反應到UI上。這樣雙向的互動,簡化不少元件互動上的coding功夫。

今天要來介紹的Knockout.js,就是能透過JavaScript來做到這件事
在進入Knockout.js細節之前,就讓我們先從範例來理解。

讓我們先從一個簡化的報名系統開始好了。

UI大致如下圖:

使用者只要點了「我要報名」,人數的統計就會累加上去。

這個報名系統的HTML如下:

<div id="register">
  <h1>報名系統</h1>
  <div>目前有<strong>0</strong>人報名</div>
  <button>我要報名</button>
</div>

[jQuery vs Knockout.js作法比一比]

依照jQuery最直覺的作法,可能是:
1.取得報名人數的DOM
2.綁定button的click事件,在點擊時把人數加1,然後再把數字塞回DOM裡面

寫法大概就是這樣:

var counter = $('#register div strong');

$('#register button').click(function(){
    var counterValue = counter.text();
    counter.text(++counterValue);
});

​那麼換作Knockout.js要怎麼做呢?

首先它必須要在綁定的HTML上,加上data-bind的標記,告訴Knockout.js資料要繫連的方式以及和它對應的資料,就像下面的做法:

<div id="register">
  <h1>報名系統</h1>
  <div>目前有<strong data-bind="text:counter">0</strong>人報名</div>
  <button data-bind="click:increase">我要報名</button>
</div>
​

接下來,就換Knockout.js登場了。它的思維是,建立一個ViewModel物件,讓Knockout.js去綁定這個ViewModel,之後的工作,就全部交由Knockout.js來處理了。

我們先來看程式碼:

function CounterViewModel() {
  this.counter = ko.observable(0);
  this.increase = function() {
    var counterValue = this.counter();
    this.counter(++counterValue);
   };
}

ko.applyBindings(new CounterViewModel());​

我們先建立一個CounterViewModel的建構式函式作為ViewModel物件,這個物件中,包含了一屬性、一個方法。this.counter用來記錄counter值,而this.increase方法,則是用來處理按鈕按下時,為counter數加1。

在這裡我們看到第一個陌生的方法:ko.observable(),簡單地說,Knockout.js知道值改變並自動去更新,靠的就是透過ko.observable()來監看值的動態。因為要綁定的值,必須把它當作ko.observable()的參數傳入,然後再指定給ViewModel的屬性,這樣一來Knockout.js之後就可以替我們處理了。

接下則是ko.applyBindings這個方法,它其實就是註冊一個ViewModel,讓它可以套用資料繫連的工作。

我們看一下HTML中兩個data-bind的tag,對應的就是ViewModel的值和方法。這裡很特別的是,我們沒有看到任何的事件註冊,像是jQuery中的click綁定,事實上透過data-bind="click:increase" 這個值的指定,已經做完事件監聽了。

至此,Knockout.js已經完工了。
jQuery版本的DEMO
http://jsfiddle.net/brecht/fYvvU/5/

Knockout.js的DEMO
http://jsfiddle.net/brecht/VgZ9k/

[Knockout.js的威力在...]

表面上看起來,似乎Knockout.js寫的code沒有精簡多少,而且還得建立一個ViewModel,看起來沒有比jQuery直覺容易。

的確,表面上看起來是如此,不過就讓我們來試試Knockout.js的威力所在。
我們來替HTML加上的個<h2>的tag,然後一樣讓它顯示報名的數量。

首先先來看jQuery的HTML:

<div id="register">
  <h1>報名系統</h1>
  <div>目前有<strong>0</strong>人報名</div>
  <button>我要報名</button>
</div>

<h2><strong>0</strong>人報名</h2>


最底下的那行h2,用來顯示和原來報名人數一樣的數字。

那麼jQuery必須針對新加入的h2做一點處理。

var counter = $('#register div strong');

var counterH2 = $('h2 strong');

$('#register button').click(function(){
     var counterValue = counter.text();
     counterValue = ++counterValue;
     counter.text(counterValue);
     counterH2.text(counterValue);
});
​

就如同counter的DOM一樣,我們先抓住H2的DOM,存在counterH2中,然後在點擊事件時,一樣把新的值塞給它(DEMO看這裡:http://jsfiddle.net/brecht/fYvvU/4/)。

那麼Knockout.js又是怎麼處理的呢?讓我們先看HTML。

<div id="register">
  <h1>報名系統</h1>
  <div>目前有<strong data-bind="text:counter">0</strong>人報名</div>
  <button data-bind="click:increase">我要報名</button>
</div>
 
<h2><strong data-bind="text:counter">0</strong>人報名</h2>

我們一樣為h2/strong加上data-bind的屬性。

然後就收工了。

什麼??JavaScript改都不用改??

沒錯,一個字都不用改,直接跑起來的結果就和jQuery的版本一樣。
這就是Knockout.js的威力所在啊(DEMO看這裡:http://jsfiddle.net/brecht/VgZ9k/1/)。

在體驗了Knockout.js的威力之後,下一次,我們會再深入一下Knockout.js的細節。如果你已經等不及的話,也可以到官網去看看,裡面的教學和文件,也可以讓你很快就上手。

[相關資源]

Knockout.js官網:http://knockoutjs.com/
Knockout.js下載:http://github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
逮丸逮丸
iT邦大師 1 級 ‧ 2012-05-29 07:52:30

新的framework出現得好多,目不睱給,
看了這篇具體實例的介紹,
勝讀三天的相關介紹。
也想知道,又有backbone.js或其他的framework,
好像各有不同的 M或V或C的 架構組合,
那麼多種的framework,
怎麼判斷何種適合解決怎樣的問題?
還是任何frmework都可解決任何問題?

這個問題好像也是:
有那麼多種的nosql,
哪種nosql適用在何種的問題 似的。

wordsmith iT邦高手 1 級 ‧ 2012-05-29 10:05:19 檢舉

我也有類似的感覺啊,想說那麼多東西,看來看去也不太有感覺,就乾脆用寫文章的方式來學習。

現在是 MV* 盛行 的時代啊~

0
misswhite
iT邦新手 4 級 ‧ 2012-05-29 16:39:11

DEMO那個好方便。讚

wordsmith iT邦高手 1 級 ‧ 2012-05-30 12:25:11 檢舉

對啊,很好用

0
wordsmith
iT邦高手 1 級 ‧ 2012-05-30 11:10:20

12种JavaScript MVC框架之比较:http://news.cnblogs.com/n/144303/

裡面比較了

&lt;pre class="c" name="code">Backbone.js
SproutCore
Sammy.js
Spine.js
Cappuccino
Knockout.js
Javascript MVC
GWT(Google Web Toolkit)
Google Closure
Ember.js
Angular.js
Batman.js

而最後作者覺得Ember.js勝出。

我要留言

立即登入留言