監控屬性(Observables)前端
knockout的三個核心特色:設計模式
1.監控屬性與依賴跟蹤瀏覽器
2.聲明式綁定app
3.模板函數
本頁,你將學習上述三個特性。可是在這以前,先了解一下MVVC模式,及 視圖模型(view model)的概念。學習
MVVM和視圖模型(View Models)this
MVVM : Model-View-View Model 是一種設計模式。它使很複雜的用戶界面使用一個很簡單的方式實現,它包括以下三部分:spa
模型(model): 表示您的業務對象和邏輯(例如:銀行帳號匯款),這是和你的UI獨立的部分。使用KO的時候,須要調用Ajax調用服務端方法讀取或寫入數據。翻譯
視圖模型(view model):UI層面的數據和操做的代碼表示。例如,編輯一個列表,view model是一個list對象,而且會有add、remove項的操做。設計
注意,這個HTML界面是不一樣的,它只保存臨時的前端數據(非持久化),view model只是純粹的JS對象。
視圖(view):KO裏,視圖能夠理解就是HTML。(其餘囉嗦的一堆沒有翻譯)。
使用KO建立view model,就是聲明一個JS對象:
var myViewModel = { personName: 'Bob', personAge: 123 };
建立view:
The name is <span data-bind="text: personName"></span>
激活Knockout
data-bindHTML並不識別(它嚴格聽從HTML5語法, 雖然HTML4驗證器提示有不可識別的屬性但依然可用),因爲瀏覽器不識別它是什麼意思,須要在加入以下JS:
ko.applyBindings(myViewModel);
這個須要在文檔一加載完成後就執行,能夠寫在HTML的最後,也可使用JQuery的$。
這樣作完以後,HTML等效於:
The name is <span>Bob</span>
applyBindings的參數說明:
第一個參數:view model
第二個參數:可選的,一個DOM對象。 若是指定這個參數,將會限定綁定行爲只發生在這個DOM的範圍及子元素內。
如:ko.applyBindings(myViewModel, document.getElementById('someElementId'))。
好處是你能夠在同一個頁面聲明多個view model,用來區分區域。
監控屬性(Observables)
上述已經建立了簡單的view model,以及把它顯示在界面上。 但KO的核心是當view model改變時自動更新界面。這要怎麼作呢?答案是使用observables。
例如,重寫上面的例子:
view model:
var myViewModel = { personName: ko.observable('Bob'), personAge: ko.observable(123) };
view 不用改。這時,當view model的值改變時,界面就會自動更改內容了。
讀取、更改監控屬性(observables)
讀取:myViewModel.personName() 返回 'Bob', and myViewModel.personAge() 返回 123.
更改值:myViewModel.personName('Mary')
一次改變多個值:myViewModel.personName('Mary').personAge(50)
監控屬性(observables)的特徵就是監控(observed),例如其它代碼能夠說我須要獲得對象變化的通知,因此KO內部有不少內置的綁定語法。因此若是你的代碼寫成data-bind="text: personName", text綁定註冊到自身,一旦personName的值改變,它就能獲得通知。
固然調用myViewModel.personName('Mary')改變name的值,text綁定將自動更新這個新值到相應的DOM元素上。這就是如何將view model的改變傳播到view上的。
監控屬性(Observables)的顯式訂閱(Explicitly subscribing to observables)
一般狀況下,你不用手工訂閱,因此新手能夠忽略此小節。高級用戶,若是你要註冊本身的訂閱到監控屬性(observables),你能夠調用它的subscribe 函數。例如:
myViewModel.personName.subscribe(function(newValue) { alert("The person's new name is " + newValue); });
subscribe函數參數:
callback 是一個funcation,當值改變時調用
target(可選),是callback函數中的this值
event(可選) 事件的名稱,默認是change
這個subscribe 函數在內部不少地方都用到的。你也能夠終止本身的訂閱:首先獲得你的訂閱,而後調用這個對象的dispose函數,例如:
var subscription = myViewModel.personName.subscribe(function(newValue) { /* do stuff */ }); // ...then later... subscription.dispose(); // I no longer want notifications
若是你要在值改變前獲得通知,可使用beforeChange這個event,例如:
myViewModel.personName.subscribe(function(oldValue) { alert("The person's previous name is " + oldValue); }, null, "beforeChange");
注意:knockout不保證beforeChange和change必定成對出現。(後面的沒看懂,大概意思是:)若是須要跟蹤改變前的值,須要另外實現對值的跟蹤。
強迫監控行爲一直髮生(Forcing observables to always notify subscribers)
通常狀況下,當值改變時,KO會捕獲到變化,並實施跟蹤。可是當值更改先後同樣時,這個通知是不會發出的,此時可使用extender來確保這個通知一直髮生,例如:
myViewModel.personName.extend({ notify: 'always' });
延時 而且/或 抑制 監控屬性改變後的通知(Delaying and/or suppressing change notifications)
通常狀況下,一但值改變了,監控屬性的通知就會立刻觸發。可是在某些狀況下(如改變是重複的,或者處理值的改變的開銷比較大),須要延後或者是限制通知產生。此時可使用rateLimit這個擴展,例如:
// Ensure it notifies about changes no more than once per 50-millisecond period myViewModel.personName.extend({ rateLimit: 50 });