• 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>
  • 相关阅读:
    linux串口驱动分析
    redis 源代码分析(一) 内存管理
    EJB3.0开发环境的搭建
    Google App Engine 学习和实践
    用EnableMenuItem不能使菜单变灰的原因
    hdu 1171 Big Event in HDU(母函数)
    Stack-based buffer overflow in acdb audio driver (CVE-2013-2597)
    遗传算法入门到掌握(一)
    Amazon SQS简单介绍 上篇
    Matlab画图-非常具体,非常全面
  • 原文地址:https://www.cnblogs.com/kubimiantiao/p/4303252.html
Copyright © 2020-2023  润新知