如果說jQuery是林志玲,那麼knockout.js可比陳妍希,同樣讓人一見傾心!! 這就是我初見knockout.js的感想。

knockout.js是一套JavaScript UI程式庫,主要用來在網頁實現MVVM設計模式。MVVM已在微軟WPF/Silverlight/WP7中廣泛應用(延伸閱讀: InfoQ的簡要介紹、微軟的MVVM導論天空的垃圾場則有幾篇WPF MVVM入門範例),用白話來說:

在MVVM裡,UI操作涉及的資料被包成ViewModel類別,接著在UI輸入/顯示元素分別標註其對應到ViewModel某個屬性值。當程式碼改變ViewModel屬性值,其對應的輸入/顯示欄位元素便會自動更新;而在UI欄位填入不同內容,ViewModel的資料屬性也會立刻被修改為新值。

這種雙向繫結(Two-Way Binding)的概念,若使用傳統做法得在ViewModel的屬性修改事件寫程式將新值反應到某個顯示/輸入元素上,還得攔截輸入元素的onChange事件,用程式將最新輸入結果反應到ViewMode屬性上,瑣碎的實做細節蠻多的。而不管是Silverlight/WPF或JavaScript,MVVM程式庫的目標即在節省前述自行開發的工夫,只需在顯示/輸入元素上註明其對應的ViewModel屬性,之後全部交給程式庫自動處理,讓程式開發者能優雅地實現MVVM。

如今,MVVM概念也被搬到網頁開發上,未來大家在ASP.NET MVC的展示中應就會常看到它。在JavaScript領域,過去也有些MVVM程式庫被提出來,例如: 微軟主導的jQuery Data Link Plugin(不過,它跟jQuery Template Plugin一樣,已停止發展,未來會由jsView及jsRender接替,但預估要到2012年中才會進入Beta階段),但顯然都比不上knockout.js所受到的關注與歡迎。

knockout.js的主要特色為:

  • 宣告式語法: 透過DOM元素Attribute宣告完成資料繫結(Data Binding),簡潔方便
  • 自動UI更新: 只要Model資料改變,UI立即反映
  • 相依性追蹤: 源頭資料變動時,可自動追溯所有關連的資料一起改變
  • 支援範本(Template): 開放自訂Template決定Model資料輸出結果,可滿足各式客製需求
  • 免費、Open Source
  • 純JavaScript - 可跟jQuery或其他JavaScript Framework併用無虞
  • 輕薄短小,Minified版本只有40KB,HTTP壓縮後只有14KB
  • 跨瀏覽器! 支援IE6+, FF2, Chrome, Opera, Safari(含行動裝置版本)

要開始體驗knockout.js,建議可由官方網站上超神奇的Web互動教學入門:

教學網站如上所示,網站左上區塊為操作說明,右上為HTML標籤區,右下方為程式碼區,左下區塊則可立即測試結果。按照操作說明,一個步驟一個步驟在HTML區及程式碼區輸入適當的標籤及程式碼,就能立即體驗knockout.js的魔力。另外,官方網站也有極其詳盡的Knockout API說明,則是深入了解knockout.js的有效途徑。

要在ASP.NET專案中體驗knockout.js,最簡單的方法是透過NuGet下載程式庫:

接著寫幾行程式,就能體驗MVVM的威力,如以下的範例:

<!DOCTYPE html>
<html>
<head>
    <title>knockout.js First Lab</title>
    <script src="../Scripts/knockout-2.1.0.debug.js"></script>
</head>
<body>
    <input type="text" id="txtValue" data-bind="value: myValue" />
    <span id="spnValue" data-bind="text: myValue"></span>
    <script type="text/javascript">
        var myViewModel =
        {
            myValue: ko.observable("Darkthread")
        }
        ko.applyBindings(myViewModel);
    </script>
</body>
</html>

在以上網頁,我宣告了一個<input>一個<span>,並定義了只有一個myValue屬性的超簡單ViewModel: myViewModel物件。透過data-bind="value: myValue"將myValue屬性綁到<input>的value值,透過data-bind="text: myValue"將屬性反映到<span>中,而myValue需透過ko.observable()宣告,knockout.js才能偵測到屬性值的變化,以便連動所有相關的UI元素。最後,要呼叫ko.applyBindings()將myViewModel繫結到網頁元素上,由於本例未引用jQuery,無$.ready()可用,所以把<script>放在網頁的最後端以確保ko.applyBindings()在網頁元素都載入後才執行。

網頁運行後,<input>與<span>一開始會顯示Darkthread,試著改變<input>的值,可發現<span>會馬上反應修改後的結果。很酷吧!!

我對ASP.NET MVC 4提到的SPA(Single Page Application)很有興趣,而knockout.js是其中重要的一環,將陸續分享一些學習心得。

PS: SPA最簡單的比喻就是像GMail那種在同一個網頁中做完全部操作,不觸發任何PostBack的設計哲學。之前我在jQuery教學中也做過粗淺示範,但當時是純手工打造,未來在ASP.NET MVC架構下實現,已有許多現成配套,相關的3rd Party程式庫也更成熟,將會省力很多。

[KO系列]

http://www.darkthread.net/kolab/labs/default.aspx?m=post

Comments

# by david.net

哈~~ 黑大先寫開箱文了~~ 讚!! 那我就可以接下來寫一些應用上的介紹^^

# by gattaca

搭配SignalR比較省事

# by Mesak

你好黑大,我想轉貼部分內容到我的網站上去,希望你不介意 http://demojs.blogspot.tw/2012/09/knockoutjs.html

# by lanhu21cn

求Kendo UI 教程!

# by AYS

請問一下,我想知道該怎麼從已經與前端連接的VM中,取出現在的值(或陣列內容)以供其他的JS程式使用?用JQUERY取得的值都是一些code....

# by AYS

抱歉找到了,直接VM.屬性()就好 orz

# by 支點雲端

我們是支點雲端科技,由三民補習班成立的線上教學機構,朝著建立技術人群聚地的目標前進。 不知您是否有意願貢獻所學?我的email是: vincent.leverage@gmail.om

# by Paul+Li

請問會不會和AngularJS一樣有dirty check的問題?

# by Jeffrey

to Paul+Li, 你指的是這個嗎?https://blog.darkthread.net/blog/monitor-js-object-prop-change/ Dirty Check 是我從 KO 換到 AngluarJS 最不習慣的地方,KO 需明確訂閱才會產生關聯,較麻煩但也較不會有類似困擾。

Post a comment