bootstrap是一個前端框架,解放web開發者的好東東,展現出的ui非常高端大氣上檔次,理論上可以不用寫一行css。只要在標籤中加上適當的屬性即可。
knockoutjs是一個javascript實作的mvvm框架。非常棒。例如列表資料項增減後,不需要重新刷新整個控制項片段或自己寫js增刪節點,只要預先定義模板和符合其語法定義的屬性即可。簡單的說,我們只需要關注數據的存取。
一、knockout.js簡介
1、knockout.js和mvvm
如今,各種前端框架應接不暇,令人眼花繚亂,有時不得不感嘆作為程序猿也真是苦逼,總有學不完的技術,何時是盡頭,除非你轉化!苦海無邊,回頭是不是岸,由你決定!
knockout.js是一個基於mvvm模式的輕量級的前端框架,有多輕?根據官網上方顯示的最新版本v3.4.0,僅22kb。能夠友善地處理資料模型和介面dom的綁定,最重要的是,它的綁定是雙向的,也就是說資料模型變化了,介面dom上的資料也會跟著變化,反過來,介面dom上的數據變化了,數據模型也會跟著這個變化。這樣能夠大幅減少我們的前端程式碼量,並且使得我們介面易於維護,再也不用寫一大堆事件監控資料模型和介面dom的變化了。下面部落客會根據一個使用實例來說明這兩點。
knockout.js官網:http://knockoutjs.com
knockout.js開源位址:https://github.com/knockout/knockout
mvvm模式:這是一種創建使用者介面的設計模式,mvvm把它拆分成三塊就是model、view、viewmodel,model就是資料模型,view就是我們的視圖,viewmodel就是一個視圖模型,用來綁定資料模型和視圖上面的dom元素。如果你使用過wpf和silverlight,理解這個應該不是啥問題;沒有使用過也什麼關係,看完此文,你會有一個大致的認識。
2.最簡單的實例
一般來說,如果你從零開始使用knockout.js,你至少需要做以下四部
2.1、去官網下載knockout.js文件,然後引用到view頁裡面。
<script src="~/scripts/knockout/knockout-3.4.0.min.js"></script>
注意:knockout.js不需要jquery的支持,如果你的專案需要用到jquery的相關操作,則引用jquery;否則只引用以上文件即可。
2.2、定義viewmodel
viewmodel是什麼?其實,在js裡面,它看起來就像一個json物件。我們定義一個viewmodel:
var myviewmodel = { name: "lilei", profession: "软件工程师", };
2.3、view視圖裡面定義綁定data-bind的標籤
<div> 姓名:<label data-bind="text:name"></label><br /> 职业:<input type="text" data-bind="textinput:profession" /> </div>
注意:對應input標籤的文本,需要使用textinput,而一般標籤的文字使用text即可。
2.4、啟動綁定
做了以上三步,還需要啟動knockout的綁定
ko.applybindings(myviewmodel);
做到這四部,基本上實作了一個最簡單的viewmodel的資料綁定。
如果你夠細心,你會發現ko.applybindings()方法有兩個參數,第一個就是我們需要綁定的viewmodel,第二個又是什麼呢?由ko.applybindings(myviewmodel); 可知,第二個參數是一個可選參數,它表示viewmodel綁定的標籤的作用域,比如,我們將以上程式碼改一下:
<div> 姓名:<label id="lb_name" data-bind="text:name"></label><br /> 职业:<input type="text" data-bind="textinput:profession" /> </div> ko.applybindings(myviewmodel,document.getelementbyid("lb_name"));
由此可知:第二個參數限定了myviewmodel的作用範圍,也就是說,只有在id="lb_name"的標籤上面綁定才會生效,如果第二個參數是div等容器標籤,它表示該綁定的範圍為該div下面的所有子標籤。
3、監控屬性
截止到上面的四步,我們看不到任何效果,看到的無非就是將一個json物件的資料綁定到了html標籤上面,這樣做有什麼意義呢?不是把簡單的問題複雜化嗎?別急,馬上見證奇蹟!上文說了,knockout最重要的意義在於雙向綁定,那麼如何實現我們的雙向綁定呢?答案就是監控屬性。
在knockout裡面,核心的有三個監控屬性:observables,dependentobservables,observablearray,observe的意思是觀察、觀測的意思,如果說成觀察屬性或觀測屬性感覺不太恰當,我們暫且叫監控屬性。
3.1、observables:監控屬性
我們將上面的範例改成這樣:
p>
index3 <script src="~/scripts/knockout/knockout-3.4.0.min.js"></script> <div> 姓名:<label data-bind="text:name"></label><br /> 职业:<input type="text" data-bind="textinput:profession" /> </div>
ko.observable("lilei") 這句話的意義是將viewmodel的name屬性加入成為監控屬性,一定name屬性變成監控屬性,神奇的事情就發生了,我們來看看當我們寫myviewmodel.的時候:
name由原來的屬性變成方法了,也就是說一旦加入了ko.observable(),那麼對應的屬性就會變成方法,那麼對於name的取值和賦值都需要使用myviewmodel.name()來處理。
程式碼釋疑:很顯然myviewmodel.name($(this).val()); 這句話將目前文字方塊的值賦給了name屬性,由於介面綁定了name屬性,所以label裡面的值也跟著改變了。或者你會說,這個使用textchange事件也可以做到的,只要將目前文字方塊的值賦給label標籤,也可以達到這個效果,這個不算什麼。確實,你的寫法也可以達到目的,但是我們的監控屬性的意義在於,任何地方改變了name的值,介面都會隨之變化,而不用每個地方去給label標籤賦值,js裡面只需要把關注點方法myviewmodel.name()上面即可。是不是很厲害~~
3.2、dependentobservables:監控依賴屬性
如果看了上面的監控屬性還沒過癮?下面再來看看監控依賴屬性的使用。
我們將程式碼再改下看看:
index3 <script src="~/scripts/knockout/knockout-3.4.0.min.js"></script>姓名:
职业:
描述:
程式碼釋疑:透過新增監控依賴屬性ko.dependentobservable() 將des屬性的值能同時監控到name和profession兩個的變化,其中任何一個發生變化,des綁定的標籤都會觸發改變,這樣做的最大好處就是避免了我們js去操作dom的麻煩,有點意思吧。
3.3、observablearray;監控陣列
除了上面兩種,ko也支援對陣列物件的監控。讓我們來看一個例子:
index3 <script src="~/scripts/knockout/knockout-3.4.0.min.js"></script>
程式碼釋疑:以上透過ko.observablearray()這個方法增加了對數組物件的監控,也就是說,js裡面任何地方只要對deptarr數組物件做了數組的改變,都會觸發ui給予對應。要注意的一點是,監控陣列其實是監控的陣列物件本身,對於陣列物件裡面的子物件屬性發生變化,是無法監控到的。例如我們將點擊事件改成這樣:
$(function () { $("#btn_test").on("click", function () { deptarr[1].name = "aaa"; }); });
由此說明數組監控實際上監控的是數組物件本身,對於數組裡面元素的屬性變化不會監控。如果確實需要對資料裡面物件的屬性變化進行監控,則需要再對資料裡面物件屬性使用ko.observable(),兩者合併使用。有興趣的可以試試。
4、ko裡面常見的data-bind屬性
上文中,我們使用了多個data-bind屬性,那麼在knockout裡面,到底有多少個這種data-bind的屬性呢。這裡我們列出一些常用的屬性。
4.1、text和inputtext
text,顧名思義就是文字的意思,這個綁定屬性一般用於