avalonJS-源碼閱讀(二)

avalon頁面處理(2)

上一篇文章講述的avalon刷頁面所用到的幾個函數。這篇則是主要講avalon對刷DOM刷出來的avalon自定義屬性如何處理的。javascript

數據結構

看js代碼最頭疼的就是數據流轉時的數據結構變化。html

//attr bindings
//例如 <div ms-dbclick-_abc='func'></div>
{
    type:$string,//也就是ms-...後面的信息,例如 ms-duplex 則爲        type:duplex,注意,遊覽器事件(event)如click,mousemove等統一爲type:on
    param:$string//"_abc"
    element:$node//當前節點
    name:$string//ms-dbclick-_abc
    value:$string//func
    priority:$Num//優先級。
        //"if": 10,
        //"repeat": 90,
        //"widget": 110,
        //"each": 1400,
        //"with": 1500,
        //"duplex": 2000,
        //"on": 3000
        //值越大優先級越高
}
//text  bindings  從上一篇拉過來
{
    type: "text|html",//類型
    node: node,//替換後的element
    nodeType: 3,//節點類型
    value: token.value,
    filters: token.filters
    replaceNodes:$array//[node]
    //token 爲scanExpr的返回值
}
//text token
{
    value:$string//具體值
    expr:$boolean//是否是在{{...}}內
    filters:$array|void 0 //過濾器
}
//bindingHandlers data
{
    handlerName:$name//被bindingHandlers中哪一個方法執行了解析。因爲href src等都經過attr來處理,因此經過bindings 的type屬性不可靠
    evaluator:$func//由parseExpr 生成的函數。
    ...//上面 的text bindings 和attr bindings
}

解析avalon標籤

有了數據結構後,看源碼就稍微輕鬆些了。解析標籤的功能主要存在bindingHandlers對象內。bindingHandler主要是對avalon標籤進行分類和按實際狀況進行處理,就像作javascript UI插件同樣。他所用到兩個很重要的函數分別是parseExprProxyparseExprjava

parseExpr

parseExpr的主要做用是根據ms-what{{what}}、vmodule和先前定義的filters等生成Function,並存儲在evaluator下(參看bindingHandlers data數據結構)。下面是各類生成後的function整理。node

//簡單的綁定個屬性 例如 ms-href={{name}}
function anonymous(vm1399087422863_0/**/) {
    'use strict';
    var name = vm1399087422863_0.name
    return name;
}
//帶有filter的,例如 {{name | uppercase}}
function anonymous(vm1399088892713_0,filters1399088892713/**/) {//filters1399088892713 會將全部現有filters做爲key/value傳遞進來
    'use strict';
    var name = vm1399088892713_0.name
    var ret1399088892713 = name 
    if(filters1399088892713.uppercase){
	    try{
            ret1399088892713 = filters1399088892713.uppercase(ret1399088892713)
	       }catch(e){} 
    }

    return ret1399088892713
}
//ms-duplex='name'
function anonymous(vm1399091173121_0/**/) {
    'use strict';
    return function(vvv){
	    var name = vm1399091173121_0.name;
	    if(!arguments.length){
		    return name
	    }
	    vm1399091173121_0.name= vvv;
    } 
}

//ms-on   ms-click="click"
function anonymous(vm1399093434491_0/**/) {
    'use strict';
    var click = vm1399093434491_0.click
    if(avalon.openComputedCollect) return ;
    return click;
}

上面是三個分支(第一個function和第二個function屬於同一分支)最基本的例子,複雜一些的也基本是以此作基礎衍生出來的,本身能夠嘗試着看着以上代碼寫一些複雜點的function出來,並和avalon生成的作對比。parseExpr在生成function的時候會涉及緩存生成函數和緩存函數的uniId生成。
緩存的源碼和測試demo會在後面寫上。緩存

parseExprProxy

parseExprProxy主要做用是經過調用parseExpr 生成function,而後進行相應的dom訂閱。它還幫助parseExpr處理了相似ms-href='http://{{abc}}ff{{abd}}'的分支。至於如何dom訂閱,不屬於本篇的範疇。數據結構

函數介紹

createCache

createCache:建立固定大小緩存,直接拿來收藏好了。dom

function createCache(maxLength) {
    var keys = []

        function cache(key, value) {
            if (keys.push(key) > maxLength) {
                delete cache[keys.shift()]
            }
            return cache[key] = value;
        }
    return cache;
}

var c= createCache(256);
//c("key","value")//value
//c("key")//value

小結

這篇篇幅較短,avalon關於DOM處理 ms-, {{...}}核心除了parseExpr函數外,還有bindingHandlers對象,而看這個代碼真如看javascript UI 插件同樣,沒多大激情(固然,寫的話就費勁了),因此就不去細細講述了。函數

附錄

測試demo

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="avalon.js"></script>
    </head>
    <body>
        <div ms-controller="nihao">
           <a ms-href='{{name}}'>abc</a>
           {{name|uppercase}}
           <input type='text' ms-duplex='name'/>
           <button ms-click='click'>button</button>
           <a ms-href='http://abc/{{name}}'>test parseExprProxy</a>
        </div>
        <script>
            avalon.define("nihao", function(vm) {
                vm.name='nihao'
                vm.cla=true
                vm.click=function(){
                    console.log("click!");
                    return 
                }
            })
        </script>
    </body>
</html>
相關文章
相關標籤/搜索