2.Knockout.Js(监控属性Observables)
前言
1.創建一個ViewModel
<script type="text/javascript">//1.創建一個ViewModelvar myViewModel = { personName:'aehyok', personAge:25 }; </script>2.為ViewModel創建一個聲明式綁定的簡單的View
The name is <span data-bind="text:personName"></span>3.激活Knockout
| 1 | ko.applyBindings(myViewModel); |
4.查看運行效果
Observables監控屬性
現在已經知道如何創建一個簡單的view model并且通過binding顯示它的屬性了。但是KO一個重要的功能是當你的view model改變的時候能自動更新你的界面。當你的view model部分改變的時候KO是如何知道的呢?答案是:你需要將你的model屬性聲明成observable的, 因為它是非常特殊的JavaScript objects,能夠通知訂閱者它的改變以及自動探測到相關的依賴。
例如:將上述的例子修改為
| 1 2 3 4 | var myViewModel = { ????personName: ko.observable('aehyok'), ????personAge: ko.observable(25) }; |
你根本不需要修改view – 所有的data-bind語法依然工作,不同的是他能監控到變化,當值改變時,view會自動更新。
?監控屬性的讀操作(read)
| 1 2 | ///監控屬性的讀操作(read) alert(myViewModel.personAge); |
監控屬性的寫操作(write)
| 1 2 | ///監控屬性的寫操作(write) myViewModel.personName("aehyok-Test"); |
Dependent Observables依賴監控屬性
如果你已經有了監控屬性firstName和lastName,你想顯示全稱怎么辦? 這就需要用到依賴監控屬性了 – 這些函數是一個或多個監控屬性, 如果他們的依賴對象改變,他們會自動跟著改變。
?例如:繼續在上面的ViewModel中添加兩個屬性 firstName和lastName
| 1 2 3 4 5 6 | var myViewModel = { ????personName: ko.observable('aehyok'), ????personAge: ko.observable(25), ????firstName: ko.observable('aehyok'), ????lastName: ko.observable('Leo') }; |
并且添加一個依賴監控屬性,來返回姓名的全稱
| 1 2 3 4 | ///依賴監控屬性 myViewModel.fullName = ko.dependentObservable(function () { ????return this.firstName() + " " + this.lastName(); }, myViewModel); |
并且綁定到View視圖界面上的元素
The fullname is <span data-bind="text: fullName"></span>不管firstName還是lastName改變,全稱fullName都會自動更新(不管誰改變,執行函數都會調用一次,不管改變成什么,他的值都會更新到UI或者其他依賴監控屬性上)。
優化上面fullname的監控屬性
| 1 2 3 4 | var viewModel = { ????firstName: ko.observable("aehyok"), ????lastName:ko.observable("Leo") }; |
對fullName的依賴監控屬性進行調整
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | viewModel.fullName = ko.dependentObservable({ ????read:function() { ????????return this.firstName() + " " + this.lastName(); ????}, ????write:function(value) { ????????var lastSpacePos = value.lastIndexOf(" "); ????????if(lastSpacePos>0) { ????????????this.firstName(value.substring(0, lastSpacePos)); ????????????this.lastName(value.substring(lastSpacePos + 1)); ????????} ????}, ????owner: viewModel }); |
這個例子里,寫操作的callback接受寫入的值,把值分離出來,分別寫入到“firstName”和“lastName”上。 你可以像普通情況一樣將這個view model綁定到DOM元素上,如下:
?
| 1 2 3 | <p>First name: <span data-bind="text: firstName"></span></p> <p>Last name: <span data-bind="text: lastName"></span></p> <h2>Hello, <input data-bind="value: fullName"/>!</h2> |
然后運行在文本框上錄入會看到如下效果
上面的view model演示的是通過一個簡單的參數來初始化依賴監控屬性。你可以給下面的屬性傳入任何JavaScript對象:
?1.?read — 必選,一個用來執行取得依賴監控屬性當前值的函數。
?2.write — 可選,如果聲明將使你的依賴監控屬性可寫,別的代碼如果這個可寫功能寫入新值,通過自定義邏輯將值再寫入各個基礎的監控屬性上。
?3.owner — 可選,如果聲明,它就是KO調用read或write的callback時用到的this。
Value轉換器
有時候你可能需要顯示一些不同格式的數據,從基礎的數據轉化成顯示格式。比如,你存儲價格為float類型,但是允許用戶編輯的字段需要支持貨幣單位和小數點。你可以用可寫的依賴監控屬性來實現,然后解析傳入的數據到基本 float類型里:
| 1 2 3 4 5 6 7 8 9 10 | viewModel.formattedPrice=ko.dependentObservable({ ????read:function () { ????????return "$" + this.price().toFixed(2); ????}, ????write:function(value) { ????????value = parseFloat(value.replace(/[^\.\d]/g, "")); ????????this.price(isNaN(value) ? 0 : value); ????}, ????owner:viewModel }); |
然后綁定到textbox上面
| 1 | <p>Enter bid price: <input data-bind="value: formattedPrice"/></p> |
所以,不管用戶什么時候輸入新價格,輸入什么格式,text box里會自動更新為帶有2位小數點和貨幣符號的數值。這樣用戶可以看到你的程序有多聰明,來告訴用戶只能輸入2位小數,否則的話自動刪除多余的位數,當 然也不能輸入負數,因為write的callback函數會自動刪除負號。
過濾并驗證用戶輸入
繼續在上面的ViewModel中添加兩個屬性
| 1 2 3 4 5 6 7 | var viewModel = { ????firstName: ko.observable("aehyok"), ????lastName: ko.observable("Leo"), ????price: ko.observable(22.466), ????acceptedNumericValue: ko.observable(123), ????lastInputWasValid: ko.observable(true) }; |
?然后添加一個依賴監控屬性
| 1 2 3 4 5 6 7 8 9 10 11 12 | viewModel.attemptedValue = ko.dependentObservable({ ????read: viewModel.acceptedNumericValue, ????write: function (value) { ????????if (isNaN(value)) { ????????????this.lastInputWasValid(false); ????????} else { ????????????this.lastInputWasValid(true); ????????????this.acceptedNumericValue(value); ????????} ????}, ????owner:viewModel }); |
進行綁定View視圖界面元素
| 1 2 | <p>Enter a numeric value: <input data-bind="value: attemptedValue"/></p> <div data-bind="visible: !lastInputWasValid()">That's not a number!</div> |
現在,acceptedNumericValue 將只接受數字,其它任何輸入的值都會觸發顯示驗證信息,而會更新acceptedNumericValue。
前言
如果你要探測和響應一個對象的變化,你應該用observables。
如果你需要探測和響應一個集合對象的變化,你應該用observableArray 。
在很多場景下,它都非常有用,比如你要在UI上需要顯示/編輯的一個列表數據集合,然后對集合進行添加和刪除。
使用observables數組
?1.簡單舉例
<script type="text/javascript">var myObservableArray = ko.observableArray(); ///初始化一個空的數組 myObservableArray.push("Some Value"); ///向數組中添加一個項 </script>2.關鍵點:監控數組跟蹤的是數組里的對象,而不是這些對象自身的狀態。
簡單說,將一對象放在observableArray 里不會使這個對象本身的屬性變化可監控的。當然你自己也可以聲明這個對象的屬性為observable的,但它就成了一個依賴監控對象了。一個 observableArray 僅僅監控他擁有的對象,并在這些對象添加或者刪除的時候發出通知。
3.預加載一個監控數組observableArray
如果你想讓你的監控數組在開始的時候就有一些初始值,那么在聲明的時候,你可以在構造器里加入這些初始對象。例如:
var anotherObservableArray = ko.observableArray([{ name: "Bungle", type: "Bear" }, { name: "George", type: "Hippo" }, { name: "Zippy", type: "Unknown" } ]);4.從observableArray里讀取信息
一個observableArray其實就是一個observable的監控對象,只不過他的值是一個數組(observableArray還加了 很多其他特性,稍后介紹)。所以你可以像獲取普通的observable的值一樣,只需要調用無參函數就可以獲取自身的值了。 例如,你可以像下面這樣獲取它的值:
alert('The length of the array is ' + myObservableArray().length);alert('The first element is ' + myObservableArray()[0]);理論上你可以使用任何原生的JavaScript數組函數來操作這些數組,但是KO提供了更好的功能等價函數,他們非常有用是因為:
A:兼容所有瀏覽器。(例如indexOf不能在IE8和早期版本上使用,但KO自己的indexOf 可以在所有瀏覽器上使用)
B:在數組操作函數方面(例如push和splice),KO自己的方式可以自動觸發依賴跟蹤,并且通知所有的訂閱者它的變化,然后讓UI界面也相應的自動更新。
C:語法更方便,調用KO的push方法,只需要這樣寫:myObservableArray.push(...)。 比如原生數組的myObservableArray().push(...)好用多了。
5.IndexOf和slice
indexOf 函數返回的是第一個等于你參數數組項的索引。例如:myObservableArray.indexOf('Blah')將返回以0為第一個索引的第一個等于Blah的數組項的索引。如果沒有找到相等的,將返回-1。
slice函數是observableArray相對于JavaScript 原生函數slice的等價函數(返回給定的從開始索引到結束索引之間所有的對象集合)。 調用myObservableArray.slice(...)等價于調用JavaScript原生函數(例 如:myObservableArray().slice(...))。
6.操作observableArray
observableArray 展現的是數組對象相似的函數并通知訂閱者的功能。
pop, push, shift, unshift, reverse, sort, splice
所有這些函數都是和JavaScript數組原生函數等價的,唯一不同的數組改變可以通知訂閱者:
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數組標準函數。
7.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的元素并將被刪除元素作為一個數組返回轉載于:https://www.cnblogs.com/TF12138/p/4156888.html
總結
以上是生活随笔為你收集整理的2.Knockout.Js(监控属性Observables)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 陶陶的兔二,建好啦!
- 下一篇: cobbler自动化安装详解