avalon2學習教程02之vm


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

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

  • $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多出一些特殊屬性,它們都是以$開頭的

  • $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生成。

如果一個vm的屬性 也是一個對象,那么它也會轉換為vm,叫子級vm,或子vm,內部使用slaveFactory生成。

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上。

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方法生成的。

如果監控數組的每個元素是一個對象,那么它們會轉換為頂層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樹

最后請大家點星加贊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM