前端MVVM框架avalon揭秘 - HTML编译器
2015-10-28 16:08
253 查看
MVVM试图更加清晰的讲用户界面(UI)开发从应用程序的业务逻辑与行为中心分离,因为,很多这样的模式的实现都需要利用声明式数据绑定来实现讲View(视图)工作从其他层分离
所以出现了一大堆自定义的声明式的语法:
如:Avalon
作用域绑定(ms-controller, ms-important)
模板绑定(ms-include)
数据填充(ms-text, ms-html)
类名切换(ms-class, ms-hover, ms-active)
事件绑定(ms-on,……)
显示绑定(ms-visible)
插入绑定(ms-if)
双工绑定(ms-duplex,原来的ms-model)
样式绑定(ms-css)
数据绑定(ms-data)
布尔属性绑定(ms-checked, ms-selected, ms-readonly, ms-disabled, ms-enabled)
字符串属性绑定(ms-title, ms-src, ms-href……)
万能属性绑定(ms-attr)
万能绑定(ms-bind)
数组循环绑定(ms-each)
对象循环绑定(ms-with)
等等………
顾名思义,自定义声明语法,那么游览器本身是不能识别的,那么如何游览器能过识别自定义的HTML语法,它能让你讲行为关系到HTML元素或者属性上,甚至能让你创造具有自定义行为的新元素呢,我们暂且讲这个过程称之为“HTML编译”吧。
我们先看一段HTML代码
HTML结构中充斥了大量的ms开头的自定义标签,还有{}插值表达式。。等等
avalon提供ms-controller, ms-important来指定VM在视图的作用范围。比如有两个VM,它们都有一个firstName属性,在DIV中,如果我们用 ms-controller="VM1", 那么对于DIV里面的{{firstName}}就会解析成VM1的firstName中的值。
用来处理样式
avalon通过ms-on-click或ms-click进行事件绑定,并在IE对事件对象进行修复,并统一了所有浏览器对return false的处理
其实就是把部分的行为操作提升到了dom上了,然后有框架在后台给你处理好,通过加入各种自定义的属性可以让任何的HTML元素都实现这样的行为
具体看源码的执行流程:
总的来说就是匹配每一给节点上的属性,通过匹配分配到指定的bindingHandlers处理函数上,之后的处理本章不暂时不涉及
看看命名就大概能猜出函数的作用了
1.入口函数 avalon.scan
默认从文本的根documentElement开始,如果传递了第一个elem,那么就是指定了扫描的作用域了,类似 jQuery( selector, [ context ] )
2. 执行扫描 scanTag
依次要检测是当前元素上是否有ms-skip,ms-important,ms-controller属性,用于最开始的处理
如果ms-controller存在就取出vm视图模型对象
清除这个自定义属性
执行sacnAttr 属性扫描
3. 扫描属性节点 scanAttr
attributes 属性返回包含被选节点属性的 NamedNodeMap。
如果在文档中设置了属性值,则 specified 属性返回 true.
是否是avalon的HTML指示 "ms-"开头
如果还指定了参数
能找到对应的处理函数
bindings 保存参数
4. 执行绑定 executeBindings
找到对应的类型的bindingHandlers方法,传入数据与vm对象,实现处理
移除数据绑定,防止被二次解析
5. 扫描子节点 scanNodes
其实就循环处理子节点列表了,注意要过滤空文本类型
如果是元素节点就递归循环scanTag方法
如果是文本节点就scanText
6. 扫描文本 scanText
7.抽出文本绑定 extractTextBindings
文本解析是个比较复杂的东西,可以匹配很多种情况,所以需要加入很多解析的规则
scanExpr 就是扫描的表达式的匹配
documentFragment 先把这个结构让到文档碎片中,性能处理
8. 表达式匹配scanExpr
代码很长,但是处理的东西确很简单的
比如:
"{{ w }} x {{ h }}" 一个插值表达式,那么应该如何解析
分析这个表达式,解析可以分三块
1. {{ w }}
2 x
3 {{ h }}
左右两边都是vm视图所有关联的属性,中间x就是求值
那么解析的规则,分解3个部分,组成处理数据
tokens 就有3个组成对象
expr: true
filters: undefined
value: " w "
expr: false
value: " x "
expr: true
filters: undefined
value: " h "
解析后分解成绑定的数据
然后就是一次循环了, 遇到条件stopScan就终止了
所以总结scan无非就干了一件事,扫描到指定的行为,发送数据给处理函数
如果您看完本篇文章感觉不错,请点击一下右下角的【推荐】来支持一下博主,谢谢!
所以出现了一大堆自定义的声明式的语法:
如:Avalon
作用域绑定(ms-controller, ms-important)
模板绑定(ms-include)
数据填充(ms-text, ms-html)
类名切换(ms-class, ms-hover, ms-active)
事件绑定(ms-on,……)
显示绑定(ms-visible)
插入绑定(ms-if)
双工绑定(ms-duplex,原来的ms-model)
样式绑定(ms-css)
数据绑定(ms-data)
布尔属性绑定(ms-checked, ms-selected, ms-readonly, ms-disabled, ms-enabled)
字符串属性绑定(ms-title, ms-src, ms-href……)
万能属性绑定(ms-attr)
万能绑定(ms-bind)
数组循环绑定(ms-each)
对象循环绑定(ms-with)
等等………
顾名思义,自定义声明语法,那么游览器本身是不能识别的,那么如何游览器能过识别自定义的HTML语法,它能让你讲行为关系到HTML元素或者属性上,甚至能让你创造具有自定义行为的新元素呢,我们暂且讲这个过程称之为“HTML编译”吧。
我们先看一段HTML代码
声明1:
声明2:
声明3:
其实就是把部分的行为操作提升到了dom上了,然后有框架在后台给你处理好,通过加入各种自定义的属性可以让任何的HTML元素都实现这样的行为
具体看源码的执行流程:
总的来说就是匹配每一给节点上的属性,通过匹配分配到指定的bindingHandlers处理函数上,之后的处理本章不暂时不涉及
1.入口函数 avalon.scan
avalon.scan
默认从文本的根documentElement开始,如果传递了第一个elem,那么就是指定了扫描的作用域了,类似 jQuery( selector, [ context ] )
2. 执行扫描 scanTag
avalon.scan
依次要检测是当前元素上是否有ms-skip,ms-important,ms-controller属性,用于最开始的处理
如果ms-controller存在就取出vm视图模型对象
清除这个自定义属性
执行sacnAttr 属性扫描
3. 扫描属性节点 scanAttr
avalon.scan
attributes 属性返回包含被选节点属性的 NamedNodeMap。
如果在文档中设置了属性值,则 specified 属性返回 true.
是否是avalon的HTML指示 "ms-"开头
如果还指定了参数
能找到对应的处理函数
bindings 保存参数
4. 执行绑定 executeBindings
avalon.scan
找到对应的类型的bindingHandlers方法,传入数据与vm对象,实现处理
移除数据绑定,防止被二次解析
5. 扫描子节点 scanNodes
avalon.scan
其实就循环处理子节点列表了,注意要过滤空文本类型
如果是元素节点就递归循环scanTag方法
如果是文本节点就scanText
6. 扫描文本 scanText
avalon.scan
7.抽出文本绑定 extractTextBindings
avalon.scan
文本解析是个比较复杂的东西,可以匹配很多种情况,所以需要加入很多解析的规则
scanExpr 就是扫描的表达式的匹配
documentFragment 先把这个结构让到文档碎片中,性能处理
8. 表达式匹配scanExpr
avalon.scan
代码很长,但是处理的东西确很简单的
比如:
"{{ w }} x {{ h }}" 一个插值表达式,那么应该如何解析
分析这个表达式,解析可以分三块
1. {{ w }}
2 x
3 {{ h }}
左右两边都是vm视图所有关联的属性,中间x就是求值
那么解析的规则,分解3个部分,组成处理数据
tokens 就有3个组成对象
expr: true
filters: undefined
value: " w "
expr: false
value: " x "
expr: true
filters: undefined
value: " h "
解析后分解成绑定的数据
然后就是一次循环了, 遇到条件stopScan就终止了
所以总结scan无非就干了一件事,扫描到指定的行为,发送数据给处理函数
如果您看完本篇文章感觉不错,请点击一下右下角的【推荐】来支持一下博主,谢谢!
相关文章推荐
- jsp乱码,xml配置方法
- Html 中表格导出生成excel文件,解决中文导出失败问题。
- javascript——defer和async的区别
- jsp+ajax实现的局部刷新较验验证码(onblur事件触发较验)
- js的小案例的实现效果学习笔记
- "undefined reference to" 问题解决方法
- jquery $(document).ready() 与window.onload的区别
- window.opener方法的使用 js跨域
- extjs增删改查(自己调用extjs)
- JQuery 获取父Frame里的元素
- DOM操作style样式——<link>、<style>、<p style=''>的区别
- Jquery 禁止客户端缓存
- HTML中Input输入框提示/设置禁用/自动获取焦点
- Fedora 22安装后无法找到Realtek无线网卡的解决
- window.opener方法的使用 js跨域
- JSP中文乱码问题终极解决方案
- AngularJS之Provider, Value, Constant, Service, Factory, Decorator的区别与详解
- JQuery 知识点(find;is)
- iOS开发日记38-MVVM与ReactiveCocoa
- javascript中new操作符