avalonJS-源码阅读(二)

 

上一篇文章讲述的avalon刷页面所用到的几个函数。这篇则是主要讲avalon对刷DOM刷出来的avalon自定义属性如何处理的。



目录[-]

avalon页面处理(2)

数据结构

解析avalon标签

parseExpr

parseExprProxy

函数介绍

createCache

小结

附录

测试demo



avalon页面处理(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。

parseExpr



parseExpr的主要作用是根据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会在后面写上。

parseExprProxy



parseExprProxy主要作用是通过调用parseExpr 生成function,然后进行相应的dom订阅。它还帮助parseExpr处理了类似ms-href='http://{{abc}}ff{{abd}}'的分支。至于如何dom订阅,



不属于本篇的范畴。

函数介绍

createCache



createCache:创建固定大小缓存,直接拿来收藏好了。

 

    

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>

 

你可能感兴趣的:(val)