avalon2學習教程02之vm

avalon2的vm是一個很是重要的東西,其設計原型最初脫胎於knockout.js,但到avalon1.6中,終於尋得本身的方案,更精簡,更易用,更魔幻。javascript

vm是一種特殊的數據結構,看起來像普通對象,但它大部分屬性都被重寫了,從而實現「操做數據即操做視圖」的效果。咱們在定義vm時,通常須要定義$id,其次是其餘業務數據屬性,它們都是來自後端的數據表。在1.4,1.5中,還有一個叫$skipArray的數組,用於方置一些只用同步一次視圖的屬性名,這是爲了提升性能。由於將普通屬性轉換能同步視圖的特殊屬性,咱們通常稱之爲監控屬性(knockoutjs是這麼叫的),其真正術語叫訪問器屬性。此外1.4與knockout同樣,能定義計算屬性,但2.0已經廢掉,這裏就不詳述了!html

  • $id vm的ID名,用於ms-controller
  • $skipArray, 數組, 用於指定那些屬性不用轉換監控屬性, 這個在定義時指定, 生成後的vm並不存在。
var vm = avalon.define({
    $id: 'test',
    a: 11,
    b: 22
})
vm.$watch('a', function(newValue, oldValue){

})

console.log(vm)

打開控制檯,咱們還會發現vm多出一些特殊屬性,它們都是以$開頭的java

  • $events, 用於放咱們的$watch回調
  • $fire, 用於觸發某一個屬性的全部回調
  • $watch, 用於監聽某個屬性的變化,當它變化時,將對應回調依次執行
  • $hashcode, $id可能有重複,但$hashcode不會重複
  • $track, 這是一個字符串,裏面包括vm的全部屬性名(除了那些內置的$開頭屬性),以;;隔開(這用於內部對象轉換的)
  • $model, 返回純淨的JS對象

  • $element, 同名的ms-controller元素節點,這是應社區的要求,怎麼經過vm獲得元素
  • $render, 靈感來自react的render方法,用於生成對應的虛擬DOM樹
  • accessors, 儲存全部監控屬性的定義,這在avalon.modern及avalon.next不存在,avalon.modern能夠經過 Object.getOwnPropertyDescriptor獲得訪問器屬性的定義,而avalon.next是使用Proxy實現vm,徹底沒有這方面的必要。

一般咱們把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次,咱們先忽視調試信息。

  1. 首先前兩個是vm3.a的值發生改變,由111變成22, 因爲vm3.a實際上與vm1.a是同一個東西,所以都觸發了。
  2. 其次中間兩個是vm3.b的值發生變化,由222變成44,因爲vm3.b實際上與vm2.b是同一個東西,所以都觸發了。
  3. 最後是ms-duplex要將input.value同步爲vm1,a這時爲數字的22,但到了元素上,變成字符串的22, 因而又觸了兩下!

avalon.mediatorFactory是一個重要的方法,是實現ms-controller套嵌的關鍵,你們有興趣的話能夠看看其源碼。

頂層vm masterFactory 供用戶操做與保存回調與同步視圖
子vm slaveFactory 承載更多用戶數據
監控數組 arrayFactory 承載更多用戶數據
內部vm mediatorFactory 容納多個vm的數據與回調,並做爲參數傳入$render方法,生成新的虛擬DOM樹

最後請你們點星加贊

相關文章
相關標籤/搜索