標籤:
上一篇文章講述的avalon刷頁面所用到的幾個函數。這篇則是主要講avalon對刷DOM刷出來的avalon自訂屬性如何處理的。目錄[-]avalon頁面處理(2)資料結構解析avalon標籤parseExprparseExprProxy函數介紹createCache小結附錄測試demoavalon頁面處理(2) 上一篇文章講述的avalon刷頁面所用到的幾個函數。這篇則是主要講avalon對刷DOM刷出來的avalon自訂屬性如何處理的。資料結構看js代碼最頭疼的就是資料流轉時的資料結構變化。 //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外掛程式一樣。他所用到兩個很重要的函數分別是parseExprProxy和parseExpr。parseExprparseExpr的主要作用是根據ms-what、{{what}}、vmodule和先前定義的filters等產生Function,並儲存在evaluator下(參看bindingHandlers data資料結構)。下面是各種產生後的function整理。 //簡單的綁定個屬性 例如 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會在後面寫上。parseExprProxyparseExprProxy主要作用是通過調用parseExpr 產生function,然後進行相應的dom訂閱。它還協助parseExpr處理了類似ms-href=‘http://{{abc}}ff{{abd}}‘的分支。至於如何dom訂閱,不屬於本篇的範疇。函數介紹createCachecreateCache:建立固定大小緩衝,直接拿來收藏好了。 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>
avalonJS-源碼閱讀(二)