1. 程式人生 > >KnockoutJS 3.X API 第二章 資料監控(1)檢視模型與監控

KnockoutJS 3.X API 第二章 資料監控(1)檢視模型與監控

資料監控

KO的三個內建核心功能:

  1. 監控(Observable)和依賴性跟蹤(dependency tracking)
  2. 宣告繫結(Declarative bindings)
  3. 模板(Templating)

在這個頁面上,您將瞭解三種核心功能的第一種。但在此之前,讓我們來看看MVVM模式的概念和檢視模型的概念

MVVM模式和檢視模型

模型-檢視-檢視模型(MVVM)是用於構建使用者介面的設計模式。它描述瞭如何將複雜的UI分割成三個部分

  • 模型:應用程式所儲存的資料,這個資料代表了你的業務領域物件和操作(例如,可以進行資金轉賬的銀行賬戶),並獨立於任何使用者介面。當使用KO,通常會用Ajax呼叫一些伺服器端API將資料讀取和寫入此儲存模式
  • 檢視模型:可理解為UI上的資料呈現和操作後的資料暫存的表示。例如,如果你檢視一個列表,檢視模型將一系列的資料展示並暴露相關操作(新增和刪除專案)的方法。

需要注意的是,檢視模型並不參與UI的呈現方式:它不具有按鈕或顯示樣式的任何概念,不是持久化資料模型,它是使用者正在檢視或未儲存的資料。當使用KO,你的檢視模型是純JavaScript物件。

  • 檢視:代表MVVM模式狀態的可見部分,使用者的互動介面。它顯示從檢視模型的資訊,傳送命令道檢視模型(例如,當用戶點選按鈕)。當使用KO,檢視是簡單地宣告繫結到其檢視模型的HTML文件。另外,也可以使用檢視模型的資料生成HTML模板。

要建立具有KO檢視模型,只是宣告任何JavaScript物件。例如:

var myViewModel={
   personName:'Bob',
   personAge:123
};

然後,您可以建立一個非常簡單的檢視使用宣告繫結這一觀點模型。例如,下面的標記顯示personName值:

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

啟用KO的繫結關係

該data-bind屬性不屬於HTML的基礎元素屬性,但是還是可以正常執行的。但由於瀏覽器不知道這意味著什麼,你需要啟用KO的繫結關係,使之生效。

要啟用KO的繫結關係,在<script>模組中新增一行程式碼:

ko.applyBings(myViewModel);

您可以把指令碼寫在HTML文件的底部,或者你可以把它寫在HTML文件頂部並在文件DOM就緒後處理,如使用jQuery的$功能。這就行了!現在,您的檢視將顯示寫下面的HTML:

The name is <span>Bob</span>

ko.applyBings的引數

第一個引數是要告訴KO,你要繫結的檢視模型是哪個。

你可以傳遞第二個引數是定義要搜尋該文件的那一部分data-bind屬性。例如,ko.applyBindings(myViewModel,document.getElementById('someElementId'))。這限制啟用繫結檢視模型的範圍在HTML元素的ID元素為someElementId及其子元素,如果你想有多個檢視模型的啟用繫結或者每個頁面的不同區域進行模型繫結的話這種方式是很有用的。

監控(Observable)

Ok,你已經看到了如何建立一個基本檢視模型以及如何顯示繫結的屬性。但是KO的主要好處是,它會根據檢視模型變化自動更新你的UI。KO如何知道什麼時候您的檢視模型的一部分改變的呢?答案就是你需要為你的檢視模型設定observable(監控),這是特殊的JavaScript物件,可將變更通知使用者,並能自動檢測依賴關係。

例如,改寫前面的檢視模型物件,如下所示:

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

當檢視模型屬性值發生變化時,會自動更新UI中的data-bind的繫結屬性。同理UI中繫結屬性發生變化時也會自動同步到檢視模型中區。

讀寫監控屬性

  • 要讀取監控屬性的當前值,只需呼叫檢視模型屬性的無引數方法。在這個例子中,myViewModel.personName()將返回‘Bob’,myViewModel.personAge()返回123.
  • 為了賦值一個新值到監控屬性,只需要呼叫檢視模型屬性的有引數方法,將值作為引數傳遞。例如,呼叫myViewModel.personName('Mary')將更改名稱值“Mary”。
  • 將值寫入多個監控屬性的模型物件,你可以使用鏈式語法。例如,myViewModel..personName('Mary').personAge(50)將更改名稱值和年齡值為‘Mary’50

KO將可以監控監控屬性,當你寫data-bind="text:personName"時,text結合自身註冊時得到通知personName的變化。當您更改名稱值‘Mary’呼叫myViewModel.personName('Mary')時,text繫結會自動更新相關的DOM元素的文字內容。

宣告監控

你通常需要手動設定訂閱,所以初學者可以跳過這一節。

對於高階使用者,如果你想註冊自己的訂閱通知的變化監控,你可以呼叫subscribe函式。例如:

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

該subscribe函式是KO內部函式。大多數時候,你不需要用這個,因為內建的繫結和模板系統管理監控已經夠用了。該subscribe函式接受三個引數:callback是每當發生通知被呼叫的函式,target(可選)定義的值this的回撥函式,event(可選,預設為“change”)是事件接受通知的名稱。

您也可以終止訂閱,可以呼叫dispose函式,例如:

var subscription=myViewModel.personName.subscribe(function(newValue){});
subscription.dispose();

如果你想在監控發生之前執行相關業務,可以使用beforeChange事件。例如:

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

強行監控屬性實時通知使用者

當賦值一個包含原始值(一個數字,字串,布林值,或者null)監控屬性,使用內建的notified,以確保一個觀測檢測屬性的使用者總是得到通知,即使該值是相同的。

myViewModel.personName.extend({notify:'always'});

延緩或抑制更改通知

通常情況下,監控屬性值改變會立即通知其使用者。但是,如果一個監控屬性頻繁跟新會帶來高昂的資料傳輸代價,你可以通過限制或延遲變更通知獲得更好的效能。這是通過使用rareLimit增量實現:

myViewModel.personName.extend({
    rateLimit:50
});