avalon2的vm是一個很是重要的東西,其設計原型最初脫胎於knockout.js,但到avalon1.6中,終於尋得本身的方案,更精簡,更易用,更魔幻。javascript
vm是一種特殊的數據結構,看起來像普通對象,但它大部分屬性都被重寫了,從而實現「操做數據即操做視圖」的效果。咱們在定義vm時,通常須要定義$id,其次是其餘業務數據屬性,它們都是來自後端的數據表。在1.4,1.5中,還有一個叫$skipArray的數組,用於方置一些只用同步一次視圖的屬性名,這是爲了提升性能。由於將普通屬性轉換能同步視圖的特殊屬性,咱們通常稱之爲監控屬性(knockoutjs是這麼叫的),其真正術語叫訪問器屬性。此外1.4與knockout同樣,能定義計算屬性,但2.0已經廢掉,這裏就不詳述了!html
var vm = avalon.define({ $id: 'test', a: 11, b: 22 }) vm.$watch('a', function(newValue, oldValue){ }) console.log(vm)
打開控制檯,咱們還會發現vm多出一些特殊屬性,它們都是以$開頭的java
一般咱們把avalon.define建立的vm叫頂層vm,內部使用masterFactory生成。react
若是一個vm的屬性 也是一個對象,那麼它也會轉換爲vm,叫子級vm,或子vm,內部使用slaveFactory生成。git
var vm = avalon.define({ $id: 'test', a: 11, b: { c: 22 } }) console.log(vm.b)
vm.b就是一個子vm,它與頂層vm有些區別,首先其$id爲頂層vm的$id加上其屬性名構成, 即"test.b"。它少了一些系統屬性,如$element, $render, $watch, $fire, $events(這個在avalon.next存在),能夠說是一個輕量的vm。它的數據發生改動時,它不會本身處理$watch回調,而是交由頂層的vm來處理,由於全部回調都放在頂層vm的$events上。github
var vm = avalon.define({ $id: 'test', a: 11, arr: [{b:1},{b:2},{b:3}] }) console.log(vm.arr)
若是vm的子級屬性是一個數組,那麼與1.4同樣,轉換爲監控數組。監控數組就是一個push, unshift, splice, pop, shift, sort, reverse等方法被重寫的數組。它在內部是由arrayFactory方法生成的。chrome
若是監控數組的每一個元素是一個對象,那麼它們會轉換爲頂層vm, 由masterFactory生成,它們的$id名都叫作test.arr.*。這時大家明白$hashcode的用處了吧(如去重,排序)。後端
在avalon2,還提供了一個工廠來合併兩個vm數組
TODO supply a title {{@a}}數據結構
在chrome控制檯中依次打印以下:
有人可能不理解爲何輸出6次,咱們先忽視調試信息。
avalon.mediatorFactory是一個重要的方法,是實現ms-controller套嵌的關鍵,你們有興趣的話能夠看看其源碼。
頂層vm | masterFactory | 供用戶操做與保存回調與同步視圖 |
子vm | slaveFactory | 承載更多用戶數據 |
監控數組 | arrayFactory | 承載更多用戶數據 |
內部vm | mediatorFactory | 容納多個vm的數據與回調,並做爲參數傳入$render方法,生成新的虛擬DOM樹 |
最後請你們點星加贊!