文档章节

avalonJS-源码阅读(二)

lost_o0
 lost_o0
发布于 2014/05/03 13:45
字数 963
阅读 522
收藏 3

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插件一样。他所用到两个很重要的函数分别是parseExprProxyparseExpr

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>


© 著作权归作者所有

lost_o0
粉丝 11
博文 37
码字总数 31139
作品 0
烟台
私信 提问
加载中

评论(1)

许雷神
许雷神
越来越觉得js有趣和高深莫测
avalonJS-源码阅读(前)

avalon模块加载 avalon自己实现了一套可被替换的模块加载系统(AMD loader)。具体什么是AMD loader可参看doJo官方博客关于AMD loader的翻译讲解,看完之后,再继续往下看,会比较清楚些。 ...

lost_o0
2014/05/02
800
0
avalonJS-源码阅读(一)

写angularJS源码阅读系列的时候,写的太垃圾了。一个月后看,真心不忍直视,以后有机会的话得重写。这次写avalonJS,希望能在代码架构层面多些一点,少上源码、多写思路。 avalon暴露句柄方式...

lost_o0
2014/04/30
913
0
avalonjs 中的if else实现的几种方法

在学习avalonjs的过程中,发现模板中并没有if else这样的写法,不像tempalte ejs这些,所以总结了三种方法来实现,仅供在使用avalonjs的同学参考,主要是通过ms-if 表达式和方法来实现. 1.开始前的...

subying
2015/10/05
4.9K
1
avalonJS-源码阅读(三) VMODEL

avalon dom小结 看过前面三篇文章后,应该会对avalon关于dom的处理有个大体的理念。这里再理一遍:avalon通过手动触发scan函数来遍历dom。然后根据确定VMODELS的作用域,接下来便是处理用户代...

lost_o0
2014/05/05
2.3K
0
Avalonjs 2.0.5 发布,迷你易用的 MVVM 框架

Avalonjs 2.0.5 发布,此版本更新内容如下: 本版本最重要就是解决多次渲染的问题,这带来了性能的极大提高! ------------------- 组件里 onInit 会加载多次(延迟到dif...

qinerg
2016/06/17
4.1K
14

没有更多内容

加载失败,请刷新页面

加载更多

新建作业20191011121223

2.编写一个程序,发出一声警报,然后打印下面的文本: Startled by the sudden sound,Sally shouted,"By the Great Pumpkin,what was that!" #include<stdio.h>int main(){printf("\a");......

电子197朱妍
23分钟前
3
0
家庭作业——苗钰婷

2 编写一个程序,发出一声警报,然后打印下面的文本: Startled by the sudden sound, Sally shouted, "By the Great Pumpkin, what was that! #include<stdio.h>int main(){......

OSC_Okruuv
44分钟前
6
0
经典系统设计面试题解析:如何设计TinyURL(一)

原文链接: https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR 编者注:本文以一道经典的系统设计面试题:《如何设计TinyURL》的参考答案和解析为例,帮助...

APEMESH
45分钟前
6
0
2.面向对象设计原则(7条)

开闭原则 开闭原则的含义是:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。 实现方法 可以通过“抽象约束、封装变化”来实...

Eappo_Geng
47分钟前
10
0
8086汇编基础 debug P命令 一步完成loop循环

    IDE : Masm for Windows 集成实验环境 2015     OS : Windows 10 x64 typesetting : Markdown    blog : my.oschina.net/zhichengjiu    gitee : gitee.com/zhichengjiu   ......

志成就
51分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部