Knockout 官網翻譯

Knockout 新版應用開發教程之建立view models與監控屬性

  • 最近抽出點時間研究MVVM,包括司徒正美的avalon,google的angular,以及Knockout,博客園Tom的Knockout指南 時隔2年了,ko更新了很多,因此文檔也相應的變化了,因此本人從學習的角度就翻譯下官方的新的教程文章。
  • avalon就是從KO演變過來的,不過加入ng,emberjs等框架的特點,加入許多巧妙的設計,算是很短小精悍的框架了,你們有興趣能夠對比下。

Knockout是構建在3個核心的特性上的:javascript

  1. 監控屬性(Observables)和依賴跟蹤(Dependency tracking)
  2. 聲明式綁定(Declarative bindings)
  3. 模版(Declarative bindings)

這一節,你講學到3個核心特性中的第一個。 在這以前, 咱們來解釋一下MVVM模式和view model的概念。html

MVVM and View Models 概念

模型-視圖-視圖模型(MVVM)是一種設計模式用來構建用戶界面,它描述瞭如何讓一個複雜的UI界面分解成3個部分:java

  • 模型:你應用存儲的數據.數據包括對象和業務操做(例如:銀子帳戶能夠完成轉帳功能)而且獨立於任何的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,app

2
3
4
5
var myViewModel = {
     personName: 'Bob' ,
     personAge: 123
};

你能建立一個很是簡單view model 用於聲明綁定.框架

例如: 下面的代碼顯示personName 值函數

2
The name is <span data-bind= "text: personName" ></span>

激活Knockout

  • data-bind 屬性不是HTML自己持有的,儘管它很好使用(它嚴格聽從HTML5語法, 雖然HTML4驗證器提示有不可識別的屬性但依然可用),但遊覽器自己是不知道它是什麼意思的,你須要激活Knockout讓這個屬性生效

激活Knockout,須要添加以下的 <script> 代碼塊:post

2
ko.applyBindings(myViewModel);

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

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

2
The name is <span>Bob</span>

你可能比較疑惑,ko.applyBindings使用了什麼參數?

  • 第一個參數就是view model模型對象,你想要用來激活聲明綁定
  • 可選參數,你能經過第二個參數來定義上下文,也就是說能夠在指定的文檔範圍內查找 data-bind屬性
    • 例如:
      • ko.applyBindings(myViewModel, document.getElementById('someElementId'))
      • 它的如今是隻有做爲someElementId 的元素和子元素才能激活KO功能。 好處是你能夠在同一個頁面聲明多個view model,用來區分區域。

真的,很簡單

Observables 監控屬性

好了,你已經看到了如何建立一個基本的view model 而且怎麼去顯示的去綁定它的屬性。

可是KO有一個核心的功能,當你的view model發生改變的時候它會自動更新你的UI。

當你的view model發現改變時怎麼才能讓KO知道呢?

回答:你須要把模型的屬性聲明稱監控屬性,由於它是很是特殊的javascript對象,可以通知在改變的時候通知訂閱者,而且可以自動偵測依賴。

例如:改寫之前一個view model對象:

2
3
4
5
var myViewModel = {
     personName: ko.observable( 'Bob' ),
     personAge: ko.observable(123)
};

你沒必要改變全部的視圖 - 這些 data-bind 的語法繼續保持工做。不一樣的地方是它可以檢測到改變,而且當使用的時候,它將會自動更新view.

Reading and writing observables 監控屬性的讀和寫

不是全部的遊覽器都支持JavaScript getters 和 setter(* cough * IE * cough *),因此爲了兼容,ko.observable 對象實際上一個 functions.

  • 讀監控屬性當前的值,直接調用不須要參數。
    • 例如:
      • myViewModel.personName() will return 'Bob', and myViewModel.personAge() will return 123.
  • 寫一個新的值到監控屬性,調用監控屬性而且傳入一個新的值做爲一個參數。
    • 例如:
      • myViewModel.personName('Mary') 將把值變成'Mary'。
  • 在一個model對象中寫一個值到多個監控屬性,你將能用到鏈式 語法。
    • 例如:
      • myViewModel.personName('Mary').personAge(50)
      • 將把name的值變'Mary'而且age的值變成50.
  1. observables的意義就是可以被監控(observed),i.e, 其餘代碼能夠這樣說,它想要更改的通知。因此KO內部有不少內置的綁定語法。因此,當你寫data-bind="text: personName",
  2. 這個text會註冊綁定它本身被通知改變,當personName的值改變,它就能獲得通知(假設這是一個能夠observable的值)。
  3. 當你用myViewModel.personName('Mary')改變這個name值是value = ’Mary’時,text綁定將自動更新這個新值到相應的DOM元素上,這就是如何改變視圖模型自動傳播到視圖的。

Explicitly subscribing to observables 顯式訂閱監控屬性

一般來講若是你不須要手動的去設置訂閱,那麼你能夠跳過這一節。

對於高級用戶,假如你想註冊本身的訂閱通知的變化來觀察,你可以調用它的subscribe方法,例如

2
3
4
myViewModel.personName.subscribe( function (newValue) {
     alert( "The person's new name is " + newValue);
});

subscribe 方法在KO內部許多地方都被使用。大部分時間你都不須要用它,由於它是內置綁定而且是由模版系統管理訂閱。

subscribe 有三個參數:

  1. callback 回調函數,當發生的通知調用
  2. target(可選)定義在回調函數中的this
  3. event(可選默change—)接收通知的事件的名稱

你也能夠終止本身的訂閱:首先獲得你的訂閱,而後調用這個對象的dispose函數,例如:

2
3
4
var subscription = myViewModel.personName.subscribe( function (newValue) { /* do stuff */ });
// ...then later...
subscription.dispose(); // I no longer want notifications

若是你想被通知之前被監控的值,它被改變,你能夠訂閱的beforechange事件:

2
3
4
myViewModel.personName.subscribe( function (oldValue) {
     alert( "The person's previous name is " + oldValue);
}, null , "beforeChange" );

Forcing observables to always notify subscribers

當寫一個了監控屬性,它包含一個原始值時,若是dependencies依賴的observable正常狀況下只會有value發生改變纔會通知。然而,可使用內置的通知extender確保observable’s的訂閱在寫的時候老是會發出通知,即便值是相同的。你會運用extender到一個監控屬性中:

2
myViewModel.personName.extend({ notify: 'always' });
相關文章
相關標籤/搜索