avalon就是從KO演變過來的,不過加入ng,emberjs等架構的特色,加入許多巧妙的設計,算是很短小精悍的架構了,大家有興趣可以對比下。
Knockout是建構在3個核心的特性上的:
監控屬性(Observables)和依賴跟蹤(Dependency tracking)
聲明式綁定(Declarative bindings)
模版(Declarative bindings)
這一節,你講學到3個核心特性中的第一個。 在這之前, 我們來解釋一下MVVM模式和view model的概念。
<a></a>
模型-視圖-視圖模型(MVVM)是一種設計模式用來建構使用者界面,它描述了如何讓一個複雜的UI界面分解成3個部分:
模型:你應用存儲的資料.資料包括對象和業務操作(例如:銀子賬戶可以完成轉賬功能)并且獨立于任何的UI,使用KO的時候,通常說是向伺服器調用Ajax讀寫這個存儲的模型資料。
視圖模型:在UI上,純code描述的資料以及操作。例如,如果你實作清單編輯,你的view model應該是一個包含清單項items的對象和暴露的add/remove清單項(item)的操作方法。
注意這不是UI本身:它不包含任何按鈕的概念或者顯示風格。它也不是持續資料模型 – 包含使用者正在使用的未儲存資料。使用KO的時候,你的view models是不包含任何HTML知識的純JavaScript 對象。保持view model抽象可以保持簡單,以便你能管理更複雜的行為。
視圖:一個可見的,互動式的,表示view model狀态的UI。 從view model顯示資料,發送指令到view model(例如:當使用者click按鈕的時候) ,任何view model狀态改變的時候更新
使用KO的時候,你的view就是你帶有綁定資訊的HTML文檔,這些聲明式的綁定管理到你的view model上。或者你可以使用模闆從你的view model擷取資料生成HTML。
例如:建立一個KO的view model,隻需要聲明任意的JavaScript object,
2
3
4
5
<code>var</code> <code>myViewModel = {</code>
<code> </code><code>personName:</code><code>'Bob'</code><code>,</code>
<code> </code><code>personAge: 123</code>
<code>};</code>
你能建立一個非常簡單view model 用于聲明綁定.
例如: 下面的代碼顯示personName 值
<code>The name is <span data-bind=</code><code>"text: personName"</code><code>></span></code>
data-bind 屬性不是HTML本身持有的,盡管它很好使用(它嚴格遵從HTML5文法, 雖然HTML4驗證器提示有不可識别的屬性但依然可用),但遊覽器本身是不知道它是什麼意思的,你需要激活Knockout讓這個屬性生效
激活Knockout,需要添加如下的 <script> 代碼塊:
<code>ko.applyBindings(myViewModel);</code>
你可以把腳本塊放到你的HTML文檔的的底部,也可以放在頂部用jQuery的$函數加載
就這樣了!現在,如過你寫了下HTML代碼你的的視圖将顯示:
<code>The name is <span>Bob</span></code>
你可能比較疑惑,ko.applyBindings使用了什麼參數?
第一個參數就是view model模型對象,你想要用來激活聲明綁定
可選參數,你能通過第二個參數來定義上下文,也就是說可以在指定的文檔範圍内查找 data-bind屬性
例如:
<code>ko.applyBindings(myViewModel, document.getElementById('someElementId'))</code>
它的現在是隻有作為someElementId 的元素和子元素才能激活KO功能。 好處是你可以在同一個頁面聲明多個view model,用來區分區域。
真的,很簡單
好了,你已經看到了如何建立一個基本的view model 并且怎麼去顯示的去綁定它的屬性。
但是KO有一個核心的功能,當你的view model發生改變的時候它會自動更新你的UI。
當你的view model發現改變時怎麼才能讓KO知道呢?
回答:你需要把模型的屬性聲明稱監控屬性,因為它是非常特殊的javascript對象,能夠通知在改變的時候通知訂閱者,并且能夠自動偵測依賴。
例如:改寫以前一個view model對象:
<code> </code><code>personName: ko.observable(</code><code>'Bob'</code><code>),</code>
<code> </code><code>personAge: ko.observable(123)</code>
你不必改變所有的視圖 - 這些 data-bind 的文法繼續保持工作。不同的地方是它能夠檢測到改變,并且當使用的時候,它将會自動更新view.
不是所有的遊覽器都支援JavaScript getters 和 setter(* cough * IE * cough *),是以為了相容,ko.observable 對象實際上一個 functions.
讀監控屬性目前的值,直接調用不需要參數。
<code>myViewModel.personName()</code> will return <code>'Bob'</code>, and <code>myViewModel.personAge()</code> will return <code>123</code>.
寫一個新的值到監控屬性,調用監控屬性并且傳入一個新的值作為一個參數。
<code>myViewModel.personName('Mary')</code> 将把值變成'Mary'。
在一個model對象中寫一個值到多個監控屬性,你将能用到鍊式 文法。
myViewModel.personName('Mary').personAge(50)
将把name的值變'Mary'并且age的值變成50.
observables的意義就是能夠被監控(observed),i.e, 其他代碼可以這樣說,它想要更改的通知。是以KO内部有很多内置的綁定文法。是以,當你寫<code>data-bind="text: personName",</code>
<code>這個text會注冊綁定它自己被通知改變,當personName的值改變,它就能得到通知(假設這是一個可以observable的值)。</code>
<code>當你用myViewModel.personName('Mary')改變這個name值是value = ’Mary’時,text綁定将自動更新這個新值到相應的DOM元素上,這就是如何改變視圖模型自動傳播到視圖的。</code>
通常來說如果你不需要手動的去設定訂閱,那麼你可以跳過這一節。
對于進階使用者,假如你想注冊自己的訂閱通知的變化來觀察,你能夠調用它的<code>subscribe方法,例如</code>
<code>myViewModel.personName.subscribe(</code><code>function</code><code>(newValue) {</code>
<code> </code><code>alert(</code><code>"The person's new name is "</code> <code>+ newValue);</code>
<code>});</code>
subscribe 方法在KO内部許多地方都被使用。大部分時間你都不需要用它,因為它是内置綁定并且是由模版系統管理訂閱。
<code>subscribe 有三個參數:</code>
<code></code><code>callback 回調函數,當發生的通知調用</code>
<code>target(可選)定義在回調函數中的this</code>
<code>event(可選默change—)接收通知的事件的名稱</code>
你也可以終止自己的訂閱:首先得到你的訂閱,然後調用這個對象的dispose函數,例如:
<code>var</code> <code>subscription = myViewModel.personName.subscribe(</code><code>function</code><code>(newValue) {</code><code>/* do stuff */</code> <code>});</code>
<code>// ...then later...</code>
<code>subscription.dispose();</code><code>// I no longer want notifications</code>
如果你想被通知以前被監控的值,它被改變,你可以訂閱的beforechange事件:
<code>myViewModel.personName.subscribe(</code><code>function</code><code>(oldValue) {</code>
<code> </code><code>alert(</code><code>"The person's previous name is "</code> <code>+ oldValue);</code>
<code>},</code><code>null</code><code>,</code><code>"beforeChange"</code><code>);</code>
<code>myViewModel.personName.extend({ notify:</code><code>'always'</code> <code>});</code>
本文轉自艾倫 Aaron部落格園部落格,原文連結:http://www.cnblogs.com/aaronjs/p/3185488.html,如需轉載請自行聯系原作者