假如你想到偵測和相應一個對象的改變,假如你想要偵測和響應一一組合集的改變,就要用observableArray
在許多場景都是很有用的,比如你要在UI上需要顯示/編輯的一個列表數據集合,然后對集合進行添加和刪除。
Example
var myObservableArray = ko.observableArray(); // Initially an empty array
myObservableArray.push('Some value'); // Adds the value and notifies observers
去看下怎么能綁定observableArray到UI並且允許使用者修改它,看the simple list example.
關鍵點:監控數組跟蹤的是數組里的對象,而不是這些對象自身的狀態。
簡而言之,將一對象放在observableArray 里不會使這個對象本身的屬性變化可監控的。
當然你自己也可以聲明這個對象的屬性為observable的,但它就成了一個依賴監控對象了。
一個observableArray 僅僅監控他擁有的對象,並在這些對象添加或者刪除的時候發出通知。
預加載一個監控數組observableArray
假如你想要你的監控數組開始的時候不是空的,包含了一些初始化的值,你可以在構造器里加入這些初始對象。例如:
// This observable array initially contains three objects
var anotherObservableArray = ko.observableArray([
{ name: "Bungle", type: "Bear" },
{ name: "George", type: "Hippo" },
{ name: "Zippy", type: "Unknown" }
]);
從observableArray里讀取信息
在內部,一個observableArray實際上就是一個observable的監控對象,只是它的值是一個數組(observableArray增加了一些特殊的,情況如下)
所以,你可以像獲取普通的observable的值一樣,只需要調用無參函數就可以獲取自身的值了。 例如,你可以像下面這樣獲取它的值:.
alert('The length of the array is ' + myObservableArray().length);
alert('The first element is ' + myObservableArray()[0]);
嚴格的來說,你能用任何的原生javascript數組函數去操作這些數組,但是通常有一些更好的選擇,
KO的 observableArray 有一些等價的函數來處理本身,他們非常的有用是因為:
他們工作在所有的游覽器(例如,原生代碼indexOf函數,不能在IE8及其早期的版本上使用,但是KO的indexOf能夠兼容)- 在數組操作函數方面(例如push和splice),KO自己的方式可以自動觸發依賴跟蹤,並且通知所有的訂閱者它的變化,然后讓UI界面也相應的自動更新。
- 語法更方便,調用KO的push方法,只需要這樣寫:myObservableArray.push(...)。 比如原生數組的myObservableArray().push(...)好用多了。
下面講解的均是observableArray的讀取和寫入的相關函數。
indexOf
indexOf 函數返回的是第一個等於你參數數組項的索引。
例如:myObservableArray.indexOf('Blah')將返回以0為第一個索引的第一個等於Blah的數組項的索引。如果沒有找到相等的,將返回-1。
slice
slice函數是observableArray相對於JavaScript 原生函數slice的等價函數(返回給定的從開始索引到結束索引之間所有的對象集合)。
調用myObservableArray.slice(...)等價於調用JavaScript原生函數(例如:myObservableArray().slice(...))。
Manipulating an observableArray
操作一個監控數組
observableArray 展現的是數組對象相似的函數並通知訂閱者的功能。
pop, push, shift, unshift, reverse, sort, splice
所有的這些函數相當於原生代碼,並且數組改變可以通知訂閱者:
- myObservableArray.push('Some new value') 在數組末尾添加一個新項
- myObservableArray.pop() 刪除數組最后一個項並返回該項
- myObservableArray.unshift('Some new value') 在數組頭部添加一個項
- myObservableArray.shift() 刪除數組頭部第一項並返回該項
- myObservableArray.reverse() 翻轉整個數組的順序
- myObservableArray.sort() 給數組排序
- 默認情況下,是按照字符排序(如果是字符)或者數字排序(如果是數字)。
- 你可以排序傳入一個排序函數進行排序,該排序函數需要接受2個參數(代表該數組里需要比較的項),如果第一個項小於第二個項,返回-1,大於則返回1,等於返回0。例如:用lastname給person排序,你可以這樣寫:myObservableArray.sort (function (left, right) {return left.lastName == right.lastName? 0: (left.lastName < right.lastName? -1: 1) })
- myObservableArray.splice() 刪除指定開始索引和指定數目的數組對象元素。例如myObservableArray.splice(1, 3) 從索引1開始刪除3個元素(第2,3,4個元素)然后將這些元素作為一個數組對象返回。
更多observableArray 函數的信息,請參考等價的JavaScript數組標准函數。
remove和removeAll
observableArray 添加了一些JavaScript數組默認沒有但非常有用的函數:
- myObservableArray.remove(someItem) 刪除所有等於someItem的元素並將被刪除元素作為一個數組返回
- myObservableArray.remove(function(item) { return item.age < 18 }) 刪除所有age屬性小於18的元素並將被刪除元素作為一個數組返回
- myObservableArray.removeAll(['Chad', 132, undefined]) 刪除所有等於'Chad', 123, or undefined的元素並將被刪除元素作為一個數組返回
destroy and destroyAll (Note: Usually relevant to Ruby on Rails developers only)
destroy和destroyAll函數是為Ruby on Rails開發者方便使用為開發的:
- myObservableArray.destroy(someItem) 找出所有等於someItem的元素並給他們添加一個屬性_destroy,並賦值為true
- myObservableArray.destroy(function(someItem) { return someItem.age < 18 }) 找出所有age屬性小於18的元素並給他們添加一個屬性_destroy,並賦值為true
- myObservableArray.destroyAll(['Chad', 132, undefined]) 找出所有等於'Chad', 123, 或undefined 的元素並給他們添加一個屬性_destroy,並賦值為true
那么,_destroy是做什么用的?正如我提到的,這只是為Rails 開發者准備的。在Rails 開發過程中,如果你傳入一個JSON對象,Rails 框架會自動轉換成ActiveRecord對象並且保存到數據庫。Rails 框架知道哪些對象以及在數據庫中存在,哪些需要添加或更新, 標記_destroy為true就是告訴框架刪除這條記錄。
注意的是:在KO render一個foreach模板的時候,會自動隱藏帶有_destroy屬性並且值為true的元素。所以如果你的“delete”按鈕調用destroy(someItem) 方法的話,UI界面上的相對應的元素將自動隱藏,然后等你提交這個JSON對象到Rails上的時候,這個元素項將從數據庫刪除(同時其它的元素項將正常的插入或者更新)
