Knotjs教程系列
1.CBS初步(本文)
....持續增加中
CBS初步
學習Knot.js,實際上就是學習如何使用CBS。CBS使用和CSS類似的原理,將綁定邏輯從HTML中提取出來,大大地增加了系統的可維護性。
我關於Knot.js介紹的第一篇博文發表之后,有一位朋友敏銳地指出CSS設計的最重要目的之一就是復用,而CBS因為是對邏輯而不是樣式的描述,復用性並不像樣式那么強,那么CBS存在的意義又在哪里呢?
實際上CBS和CSS雖然原理類似,形式類似,但設計目的卻很不一樣。 綁定邏輯雖然復用性不如樣式,但它會比樣式復雜得多。在HTMLtag那么有限的空間里塞入大量的邏輯描述顯然對於維護性是極為不利的。CBS就是為了解決這個問題。CBS比CSS在形式上最大的不同在於CBS可以嵌套(對,就像LESS一樣),最終形成的CBS會自然和HTML結構保持一致,非常便利。同時獨立出來的CBS也能在不影響閱讀性的前提下嵌入大量的綁定邏輯,你會發現實用中的CBS中往往包含了大量的javascript嵌入函數,這些邏輯如果硬塞入HTML或者放回Javascript都不會有在CBS中那么自然恰當。
安裝
到http://knotjs.com/download/latest下載knot.js的最新版本。壓縮包里有壓縮過的knot.js主文件和debugger,引用knot.min.js,你就能在網頁里使用CBS了。
<script src="[PATH_TO_KNOTJS]/knot.min.js"></script>
如果要開啟Debugger(開發和學習時推薦開啟),再引用下Debugger的js文件knot.debug.js就好。注意啟用Debugger對性能會有較大影響,請務必在發布前移除Debugger。
<script src="[PATH_TO_KNOTJS]/debugger/knot.debug.js"></script>
注意你必須從一個web服務器上打開你的網頁,否則因為安全原因,Debugger可能無法工作。另外Debugger必須和你的網頁在一個域中。
CBS基礎
好了,讓我們開始看看CBS的基本語法吧:
CBS語法中各個部件解釋如下:
- Selector(選擇器):支持所有的標准CSS selector,同時還支持Object Selector(這個你應該很少用到,詳細可以看這里:Selector @GitHub)
- Access Point (訪問點): 表明這一項綁定將綁定到對象的什么地方。
- 左訪問點:表明綁定到選擇器選中對象的具體屬性。如果選擇器選中的是HTML對象,則可以是這些HTML對象上的任意一個屬性。注意你可以使用數據路徑(Path of value),例如使用“style.display” , 你就能直接綁定到HTML元素的style對象的display屬性上。除了HTML對象自帶的屬性外,knot.js還提供了一部分方便使用和跨瀏覽器的擴展屬性(例如后面例子中的“text”);而如果你在使用knot.js的組件,則該組件會有自己特有的訪問點,具體請參考該組件的文檔。
- 右訪問點:表明綁定到當前數據上下文對象的具體屬性名稱。注意這里也能使用數據路徑,因此如果你綁定到"user.address.postCode", 也完全沒有問題。這里也可以使用絕對路徑訪問全局變量,例如“/model.user.address.postCode”,也可以使用Target Modifier(綁定目標修改器)綁定到任意HTML元素。關於Target Modifier的問題我們以后再說。
關於Access Point我們后面會有更多的介紹。如果你現在就想了解更多,請參看這里: Access Point @GitHub
- Binding Type(綁定類型):knot.js提供四種綁定類型分布是":"(雙向綁定) 、"=>"(右向綁定), "<="(左向綁定)和"="(一次性綁定)。活用這些綁定類型可以使你最大限度地提高系統效率。不過在性能不特別敏感的場合,使用":"(雙向綁定) 就已經足夠快了,所以如果你不知道該用什么類型的話,請直接使用“:”。關於綁定類型的詳細說明,請看這個鏈接:Binding-types(Wiki@GitHub)
- 數據上下文(DataContext):通常情況下,數據上下文就是你想要綁定到HTML元素上的Javascript對象。
- 你可以通過“dataContext”訪問點來指定一個HTML元素的數據上下文。例如:
body{ dataContext: /model }
以上代碼將Javascirpt全局對象model設置為"body"元素的數據上下文。
- 數據上下文根據DOM結構具有繼承性。以1中的例子為例,頁面中所有元素的默認數據上下文都會變成model對象,除非該元素自己有一個dataContext的設置。如果某個元素有自己的dataContext設置,則它所有的子元素將全部繼承這項設置。
- 你可以通過“dataContext”訪問點來指定一個HTML元素的數據上下文。例如:
- CBS可以嵌套書寫。我非常推薦把CBS嵌套書寫,這會大幅度提高CBS的可維護性。 嵌套的CBS需要在選擇器前加一個"->"。請看例子:
/* 這是比較“傳統”的,css式的做法 */ .example input{value:name;} .example .message{text: name;} /* 改寫為CBS的嵌套形式后是這樣 */ .example{ -> input{value:name;}; -> .message{text: name;}; }
- CBS使用type="text/cbs"的script標簽來聲明。和Javascript一樣,你可以直接吧CBS放在這個標簽內,也能通過“src”屬性引用頁面外的獨立CBS文件。例如:
<script type="text/cbs" src="[PATH_TO_CBS]/example.cbs"></script>
- knot.js也支持直接把綁定配置放在HTML內的做法(雖然不推薦)
<input type="text" binding="value:name">
- 比較完整的CBS語法示例請查看這里:CBS Syntax @GitHub,其中涉及的概念和內容我會在以后詳細介紹。
示例
下面我們來看一個具體的簡單例子。這個例子就是我們在第一篇文章末尾提到的例子,只是做了一點點修改,加入了一個javascript對象。輸入姓名,顯示一個問候語。你可以點擊這個鏈接: knot.js英文版tutorial 去試用這個例子。
數據流圖是這樣的:
HTML:
<div class="knot_example"> <h3>Greeting from knot.js (V2)</h3> <p> <label>Input your name here: </label> <input type="text"> </p> <p> Hello <b class="helloString"></b> </p> </div>
Javascript:
//直接使用一個最簡單的javascript對象做model window.greetingModel = {name:"Alex"};
CBS:
<script type="text/cbs"> .knot_example { /* 設置dataContext為Javascript全局對象 window.greetingModel */ dataContext: /greetingModel; /* 綁定value到name. 因為當前Data Context是window.greetingMode, 所以這個設置也能寫為 "value[immediately:1]: /greetingModel.name" "[immediately:1]" 是一個綁定選項,表示每次擊鍵都更新數據。默認為0,表示焦點移出文本框才更新數據 */ -> input{ value[immediately:1]: name; }; /*綁定 text到 name, 同樣的,因為Data Context的存在,最終綁定到window.greetingModel.name*/ -> .helloString{ text: name; } } </script>
關於CBS,請注意以下這些點:
- 如果你想在Knot.js初始化,完成綁定之后再執行某段程序,請使用Knot.ready:
Knot.ready(function(succeed, err){ if(!succ) { global.alert(err.message); return; } // your own code.... }
- 和CSS類似,CBS也會被應用於所有被selector選中的HTML元素。例如下面這段CBS將會把頁面上所有class含有"title"的元素的text和該元素的DataContext的title屬性進行綁定
.title{ text: title }
- 並不是所有的訪問點都支持雙向綁定。例如上面例子中的".helloString"是個span,它的textContent顯然是不會自己變化的,所以它就不支持雙向綁定。因此,對它的雙向綁定實際上會變成單向綁定:
/* 雙向綁定,但因為text不支持,所以最后實際結果就是一個單向綁定 */ .helloString{text: name;} /* 單向綁定,和上面的完全等價 */ .helloString{text <= name;}
支持雙向綁定的HTML訪問點的列表請看這里:Observable HTML Access Point List @GitHub
如果你對knot.js感興趣,請關注我以獲取后續更新提醒。同時請點擊推薦此文,knot.js需要足夠的注意力來吸引開發者和建立自己的社區。
knot.js感謝你的支持。