輕量級前端MVVM框架avalon - 執行流程1


基本上確定了avalon的幾個重要元素的關系:

  • M,即model,一個普通的JS對象,可能是后台傳過來的,也可能是直接從VM中拿到,即VM.$json。有關的這個$json的名字還在商討

  • V,即View,HTML頁面,通過綁定屬性或插值表達式,呈現數據,處理隱藏,綁定事件或動畫等各種交互效果。V只與VM打交道。

  • VM,即ViewModel,我們通過avalon.define("xxx", function(vm){vm.firstName = "正美"}),這里的vm是一個臨時的對象,用於定義,真正的VM是avalon.define方法的返回值。它上面的$json屬性就是M,可以見VM處於一切的核心。我們對VM的每一個操作,都會向上同步到V,向下同步到M。並且出於節能低碳起見(減少對象的創建),我們在生成M時,會重復利用VM中的一些屬性,比如vm的某個屬性是一個對象,那么這個對象會直接搬到$json中。若它是一個數組,它里面每個元素為對象,這些數組或對象都會直接$json中去,當然有時會修復一下(比如計算屬性會轉換一個簡單的數據類型)

 

運作流程:

在MVVM模式中,ViewModel是貫穿整個框架的梁柱

我們現在分析下整個代碼如何運作的一個流程:本文不討論具體實現,只討論流程

首先自然是HTML結構

<fieldset ms-controller="simple">
         <legend>例子</legend>
         <p>First name: <input ms-model="firstName" /></p>
         <p>Last name: <input ms-model="lastName"  /></p>
         <p>Hello,    <input ms-model="fullName"></p>
         <div>{{firstName +" | "+ lastName }}</div>
     </fieldset>

觀察后得出結論:

@ 與常規結構不同

@ 定義了很多自定義標簽  如何:ms-model ,ms-controller 

@ 插值表達式 {{}}

.........等等,具體請看api手冊

 

那么接下來開發着定義JS

avalon.ready(function() { avalon.define("simple", function(vm) { vm.firstName = "司徒" vm.lastName = "正美" vm.fullName = {//一個包含set或get的對象會被當成PropertyDescriptor,
            set: function(val) {//set, get里面的this不能改成vm
                var array = (val || "").split(" "); this.firstName = array[0] || ""; this.lastName = array[1] || ""; }, get: function() { return this.firstName + " " + this.lastName; } }, vm.nick = { name: "暗黑之民" } }) })

大概理解下代碼的意思:

avalon.ready(function() {   //這是domReady,相當於jQuery的 $(function(){})
var model = avalon.define( "aaa", [], function(vm) { //創建一個名字為aaa的ViewModel vm.firstName = "司徒" //創建一個監控屬性 vm.lastName = "正美" //創建一個監控屬性 vm.fullName = { //一個包含set或get的對象 用於創建一個依賴監控屬性 avalon.scan(); //開始掃描DOM樹,處理綁定

 

第二步就能看出來這個就是定義的一個模型了,vm->ViewModel 視圖模型

整個運作都是圍繞着vm展開的,mvvm模式中VM處於一切的核心,我們對VM的每一個操作,都會向上同步到V,向下同步到M。

VM的創建不僅僅只是我們看到的定義了幾個屬性,幾個方法,其實框架內部幫我們做了很多事:


VM模型的創建:


1.框架內部創建模型對象VM

2.VM吸收開發定義的處理方法

3.把開發定義的方法給經內部的轉換,它的屬性與方法會換胎換骨

4.返回這個被改造過的模型對象,掛到全局保存起來

所以這個里面涉及閉包與作用域鏈的問題了,以后再慢慢分析





那么這個VM創建好了,我們接下來干嘛呢?

大家有沒有發現在HTML結構中與VM代碼中,有沒有共同點?


1.HTML中定義的自定義標簽與VM中的屬性方法名是不是一樣?

2.根據API的定義,HTML對應的每一個標簽的都會對應着某一種JS的處理方式

3.現在HTML結構與JS代碼都是獨立的東東,所以我們想個辦法讓他們關聯起來

如何關聯?

答案:掃描綁定

 

avalon.scan();

簡而言之呢就是掃描屬性節點,文本節點,找到對應的事件處理器,執行事件綁定等一堆東東


屬性節點

<input ms-model="firstName" />

發現有ms-開頭的名字就會解析成對應的一個處理方法

比如ms-model

//將模型中的字段與input, textarea的value值關聯在一起 var modelBinding = bindingHandlers.model = function(data, scopes) { var element = data.element; var tagName = element.tagName; //是否有對應元素的標簽名的處理方法 if (typeof modelBinding[tagName] === "function") { var array = getValueFunction(data.value.trim(), scopes); if (array) { modelBinding[tagName](element, array[0], array[1]); } }

當然還會傳遞一些需要運行的參數

特別指出來傳遞的實參scopes就是ViewModel對象



所以我們大膽猜測下

  * 在這一大堆掃描綁定方法中應該會哪些實現(這些方法才是最終的執行體)

  待續...

 


免責聲明!

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



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