avalonJS-源码阅读(2)
上一篇文章讲述的avalon刷页面所用到的几个函数。
这篇则是主要讲avalon
对刷DOM刷出来的avalon自定义属性如何处理的。
目录[-]
avalon页面处理(2)
数据结构
解析avalon标签
parseExpr
parseExprProxy
函数介绍
createCache
小结
附录
测试demo
上一篇文章讲述的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>
avalonJS-源码阅读(2)的更多相关文章
- avalon源码阅读(1)
来源 写angularJS源码阅读系列的时候,写的太垃圾了. 一个月后看,真心不忍直视,以后有机会的话得重写. 这次写avalonJS,希望能在代码架构层面多些一点,少上源码.多写思路. avalon ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 【原】FMDB源码阅读(二)
[原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...
- 【原】FMDB源码阅读(一)
[原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...
- 【原】AFNetworking源码阅读(六)
[原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...
- 【原】AFNetworking源码阅读(五)
[原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...
- 【原】AFNetworking源码阅读(四)
[原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...
- 【原】AFNetworking源码阅读(三)
[原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...
- 【原】AFNetworking源码阅读(二)
[原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...
- 【原】AFNetworking源码阅读(一)
[原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...
随机推荐
- java自学入门心得体会 0.1
之前记录了java的简介和基本语法 这里记载下对象和类 不太懂的我理解java对象和类的概念很模糊,因为有了 Abstract修饰符 让对象与类更加的扑朔迷离 - - 所以,就像很开放的语言,创建对象 ...
- [Pytorch]Pytorch的tensor变量类型转换
原文:https://blog.csdn.net/hustchenze/article/details/79154139 Pytorch的数据类型为各式各样的Tensor,Tensor可以理解为高维矩 ...
- 用 C# 计算 与 java 一致的unix时间戳 (长时间整形 如:1476956079961)
背景: 调用java提供接口,需要长时间整形作为验证. 预备知识: 1. java 的 System.currentTimeMillis() 计算的长整型,是从1970年1月1日开始,截止当前的毫秒数 ...
- UVa 1626 括号序列(矩阵连乘)
https://vjudge.net/problem/UVA-1626 题意: 输入一个由 "(" . ")" . "[" . " ...
- MySQL查询优化之性能提升一个数量级
这段时间一直在用kettle做数据抽取和报表,写SQL便是家常便饭了,200行+SQL经常要写.甚至写过最长的一个SQL500多行将近600行.这么长的SQL估计大部分人连看的意愿都没有,读起来也比较 ...
- ajax专题
什么是ajax?他可以用来做什么? 1.首先,ajax不是一种编程语言,是一种在无需重新加载整个网页的情况下能够更新部分网页的技术. 优点:通过和后台服务器进行少量的数据交换,网页就能异步的局部跟新, ...
- Cocoapods 报警告Automatically assigning platform ios with version 9.0 on target....
Automatically assigning platform iOS with version 9.0 on target 你的工程名称 because no platform was speci ...
- Unity中的文件
Unity中的文件大致分为一下几类: 1.资源文件: 导入后,除非是修改,否则不会变化的文件.例如:fbx文件.贴图文件.音频文件.视频文件.动画文件等. 这些文件在导入到Unity的时候,都会进行转 ...
- C#异常信息获取
try { ; / i; } catch (Exception ex) { /** * 1.异常消息 * 2.异常模块名称 * 3.异常方法名称 * 4.异常行号 */ String str = &q ...
- Linq 使用skip和take分页
static int Main(string[] args) { //每页条数 const int pageSize = 2; //页码 0就是第一条数据 int pageNum = 0; strin ...