天天看點

Knockout 新版應用開發教程之建立view models與監控屬性MVVM and View Models 概念激活KnockoutObservables 監控屬性Reading and writing observables 監控屬性的讀和寫Explicitly subscribing to observables 顯式訂閱監控屬性Forcing observables to always notify subscribers

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 &lt;span data-bind=</code><code>"text: personName"</code><code>&gt;&lt;/span&gt;</code>

data-bind 屬性不是HTML本身持有的,盡管它很好使用(它嚴格遵從HTML5文法, 雖然HTML4驗證器提示有不可識别的屬性但依然可用),但遊覽器本身是不知道它是什麼意思的,你需要激活Knockout讓這個屬性生效

激活Knockout,需要添加如下的 &lt;script&gt; 代碼塊:

<code>ko.applyBindings(myViewModel);</code>

你可以把腳本塊放到你的HTML文檔的的底部,也可以放在頂部用jQuery的$函數加載

就這樣了!現在,如過你寫了下HTML代碼你的的視圖将顯示:

<code>The name is &lt;span&gt;Bob&lt;/span&gt;</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,如需轉載請自行聯系原作者

繼續閱讀