Knockout是一個輕量級的UI類庫,通過應(yīng)用MVVM模式使JavaScript前端UI簡單化。
Knockout有如下4大重要概念:
聲明式綁定?**(Declarative Bindings):**使用簡明易讀的語法很容易地將模型(model)數(shù)據(jù)關(guān)聯(lián)到DOM元素上。
*UI**界面自動刷新?(Automatic UI Refresh):*當(dāng)您的模型狀態(tài)(model state)改變時,您的UI界面將自動更新。
依賴跟蹤(Dependency Tracking):為轉(zhuǎn)變和聯(lián)合數(shù)據(jù),在你的模型數(shù)據(jù)之間隱式建立關(guān)系。
簡稱:KO
官方網(wǎng)站:http://knockoutjs.com
Knockout是一個以數(shù)據(jù)模型(data model)為基礎(chǔ)的能夠幫助你創(chuàng)建富文本,響應(yīng)顯示和編輯用戶界面的JavaScript類庫。任何時候如果你的UI需要自動更新(比如:更新依賴于用戶的行為或者外部數(shù)據(jù)源的改變),KO能夠很簡單的幫你實現(xiàn)并且很容易維護。
重要特性:
額外的好處:
開發(fā)人員如果用過Silverlight或者WPF可能會知道KO是MVVM模式的一個例子。如果熟悉 Ruby on Rails 或其它MVC技術(shù)可能會發(fā)現(xiàn)它是一個帶有聲明式語法的MVC實時form。換句話說,你可以把KO當(dāng)成通過編輯JSON數(shù)據(jù)來制作UI用戶界面的一種方式… 不管它為你做什么
**OK,?**如何使用它?
簡單來說:聲明你的數(shù)據(jù)作為一個JavaScript 模型對象(model object),然后將DOM 元素或者模板(templates)綁定到它上面.
讓我們來看一個例子
想想在一個頁面上,航空旅客可以為他們的旅行升級高級食物套餐,當(dāng)他們選擇一個套餐的時候,頁面立即顯示套餐的描述和價格。首先,聲明可用的套餐:
var availableMeals = [
{ mealName: 'Standard', description: 'Dry crusts of bread', extraCost: 0 },
{ mealName: 'Premium', description: 'Fresh bread with cheese', extraCost: 9.95 },
{ mealName: 'Deluxe', description: 'Caviar and vintage Dr Pepper', extraCost: 18.50 }
];
如果想讓這3個選項顯示到頁面上,我們可以綁定一個下拉菜單(例如:元素)到這個數(shù)據(jù)上。例如:
<h3>Meal upgrades</h3>
<p>Make your flight more bearable by selecting a meal to match your social and economic status.</p>
Chosen meal: <select data-bind="options: availableMeals,
optionsText: 'mealName'"></select>
啟用Knockout并使你的綁定生效,在availableMeals變量聲明之后添加如下代碼:
var viewModel = {
/* we'll populate this in a moment */
};
ko.applyBindings(viewModel); // Makes Knockout get to work
// 注意:ko. applyBindings需要在上述HTML之后應(yīng)用才有效
你可以在這個系列里將學(xué)習(xí)更多的view model 和 MVVM?,F(xiàn)在你的頁面將render成如下的樣子:
?
響應(yīng)選擇
下一步,聲明一個簡單的data model來描述旅客已經(jīng)選擇的套餐,添加一個屬性到當(dāng)前的view model上:
var viewModel = {
chosenMeal: ko.observable(availableMeals[0])
};
ko.observable是什么?它是KO里的一個基礎(chǔ)概念。UI可以監(jiān)控(observe)它的值并且回應(yīng)它的變化。這里我們設(shè)置chosenMeal是UI可以監(jiān)控已經(jīng)選擇的套餐,并初始化它,使用availableMeal里的第一個值作為它的默認(rèn)值(例如:Standard)。
讓我們將chosenMeal 關(guān)聯(lián)到下拉菜單上,僅僅是更新的data-bind屬性,告訴它讓元素的值讀取/寫入chosenMeal這個模型屬性:
Chosen meal: <select data-bind="options: availableMeals,
optionsText: 'mealName',
value: chosenMeal"></select>
理論上說,我們現(xiàn)在可以讀/寫chosenMeal 屬性了,但是我們不知道它的作用。讓我們來顯示已選擇套餐的描述和價格:
<p>
You've chosen:
<b data-bind="text: chosenMeal().description"></b>
(price: <span data-bind='text: chosenMeal().extraCost'></span>)
</p>
于是,套餐信息和價格,將根據(jù)用戶選擇不同的套餐項而自動更新:
更多關(guān)于observables和dependency tracking的使用
最后一件事:如果能將價格格式化成帶有貨幣符號的就好了,聲明一個JavaScript函數(shù)就可以實現(xiàn)了…
function formatPrice(price) {
return price == 0 ? "Free" : "$" + price.toFixed(2);
}
… 然后更新綁定信息使用這個函數(shù) …
(price: <span data-bind='text: formatPrice(chosenMeal().extraCost)'></span>)
… 界面顯示結(jié)果將變得好看多了:
?
Price的格式化展示了,你可以在你的綁定里寫任何JavaScript代碼,KO仍然能探測到你的綁定依賴代碼。這就展示了當(dāng)你的model改變時,KO如何只進行局部更新而不用重新render整個頁面 – 僅僅是有依賴值改變的那部分。
鏈?zhǔn)降膐bservables也是支持的(例如:總價依賴于價格和數(shù)量)。當(dāng)鏈改變的時候,依賴的下游部分將會重新執(zhí)行,同時所有相關(guān)的UI將自動更新。不需要在各個observables之間聲明關(guān)聯(lián)關(guān)系,KO框架會在運行時自動執(zhí)行的。
你可以從 observables 和 observable arrays 獲取更多信息。上面的例子非常簡單,沒有覆蓋很多KO的功能。你可以獲取更多的內(nèi)嵌的綁定和模板綁定。
KO和jQuery (或Prototype等)是競爭關(guān)系還是能一起使用?
所有人都喜歡jQuery! 它是一個在頁面里操作元素和事件的框架,非常出色并且易使用,在DOM操作上肯定使用jQuery,KO解決不同的問題。
如果頁面要求復(fù)雜,僅僅使用jQuery需要花費更多的代碼。 例如:一個表格里顯示一個列表,然后統(tǒng)計列表的數(shù)量,Add按鈕在數(shù)據(jù)行TR小于5調(diào)的時候啟用,否則就禁用。jQuery 沒有基本的數(shù)據(jù)模型的概念,所以需要獲取數(shù)據(jù)的數(shù)量(從table/div或者專門定義的CSS class),如果需要在某些SPAN里顯示數(shù)據(jù)的數(shù)量,當(dāng)添加新數(shù)據(jù)的時候,你還要記得更新這個SPAN的text。當(dāng)然,你還要判斷當(dāng)總數(shù)>=5條的時候禁用Add按鈕。 然后,如果還要實現(xiàn)Delete功能的時候,你不得不指出哪一個DOM元素被點擊以后需要改變。
Knockout的實現(xiàn)有何不同?
使用KO非常簡單。將你的數(shù)據(jù)描繪成一個JavaScript數(shù)組對象myItems,然后使用模板(template)轉(zhuǎn)化這個數(shù)組到表格里(或者一組DIV)。不管什么時候數(shù)組改變, UI界面也會響應(yīng)改變(不用指出如何插入新行或在哪里插入),剩余的工作就是同步了。例如:你可以聲明綁定如下一個SPAN顯示數(shù)據(jù)數(shù)量(可以放在頁面的任何地方,不一定非要在template里):
There are <span data-bind="text: myItems().count"></span> items
就是這些!你不需要寫代碼去更新它,它的更新依賴于數(shù)組myItems的改變。同樣, Add按鈕的啟用和禁用依賴于數(shù)組myItems的長度,如下:
<button data-bind="enable: myItems().count < 5">Add</button>
之后,如果你要實現(xiàn)Delete功能,不必指出如何操作UI元素,只需要修改數(shù)據(jù)模型就可以了。
總結(jié):KO沒有和jQuery或類似的DOM 操作API對抗競爭。KO提供了一個關(guān)聯(lián)數(shù)據(jù)模型和用戶界面的高級功能。KO本身不依賴jQuery,但是你可以一起同時使用jQuery, 生動平緩的UI改變需要真正使用jQuery。
Knockout的核心類庫是純JavaScript代碼,不依賴任何第三方的類庫。所以按照如下步驟即可添加KO到你的項目里:
*Debug調(diào)試目的,可使用非壓縮版本(knockout-x.x.debug.js
).?和壓縮版本同樣的功能,但是具有全變量名和注釋的可讀性源代碼,并且沒有隱藏內(nèi)部的API。
這就是你需要的一切…
開啟模板綁定
…除非你想使用模板綁定功能(您很有可能使用它,因為非常有用),那你需要再引用兩個JavaScript文件。 KO1.3版的默認(rèn)模板引擎是依賴jQuery的jquery.tmpl.js
(最新版2.0版已經(jīng)不依賴jquery tmp了)。所以你需要下載下面的2個文件并在引用KO之前引用:
jquery-tmpl.js
?— 此版本 可以很容易使用,或者你訪問官方網(wǎng)站?查找最新版本。正確的引用順序:
<script type='text/javascript' src='jquery-1.4.2.min.js'></script>
<script type='text/javascript' src='jquery-tmpl.js'></script>
<script type='text/javascript' src='knockout-1.2.1.js'></script>
(當(dāng)然,您要根據(jù)你的文件路徑累更新上面的文件路徑和文件名。)
下一步,開始學(xué)習(xí) 監(jiān)控屬性。
更多建議: