作用域绑定(ms-controller, ms-important)
如果一个页面非常复杂,就需要划分模块,每个模块交由不同的ViewModel去处理。我们就要用到ms-controller与ms-important来指定ViewModel了。
我们看下面的例子:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script src="js/avalon.js" type="text/javascript" charset="utf-8"></script> </head> <body> <div ms-controller="AAA"> <div>{{name}} : {{color}}</div> <div ms-controller="BBB"> <div>{{name}} : {{color}}</div> <div ms-controller="CCC"> <div>{{name}} : {{color}}</div> </div> <div ms-important="DDD"> <div>{{name}} : {{color}}</div> </div> </div> </div> <script type="text/javascript"> avalon.ready(function() { avalon.define({ $id: "AAA", name: "liger", color: "green" }); avalon.define({ $id: "BBB", name: "sphinx", color: "red" }); avalon.define({ $id: "CCC", name: "dragon" //不存在color }); avalon.define({ $id: "DDD", name: "sirenia" //不存在color }); avalon.scan() }) </script> </body> </html>
可以看出ViewModel在DOM树的作用范围其实与CSS很相似,采取就近原则,如果当前ViewModel没有此字段 就找上一级ViewModel的同名字段,这个机制非常有利于团队协作。
如果从另一个角度来看,由于这种随机组成的方式就能实现类似继承的方式,因此我们就不必在JS代码时构建复杂的继承体系。
类的继承体系是源自后端复杂业务的膨胀而诞生的。早在20世界80年代初期,也就是面向对象发展的初期,人们就非常看重继承这个概念。 继承关系蕴涵的意义是非常深远的。使用继承我们可以基于差异编程,也就是说,对于一个满足我们大部分需求的类,可以创建一个它的子类,重载它个别方法来实现我们所要的功能。只子继承一个类, 就可以重类该类的代码!通过继承,我们可以建立完整的软件结构分类,其中每一个层都可以重用该层次以上的代码。这是一个美丽新世界。
但类继承的缺点也是很明显的,在下摘录一些:
面向对象语言与生俱来的问题就是它们与生俱来的这一整个隐性环境。你想要一根香蕉,但你得到的是一头手里握着香蕉的大猩猩,以及整个丛林。 -- Joe Armstrong
在适合使用复合模式的共有类中使用继承,会把这个类与它的超类永远地束缚在一起,从而人为地限制了子类的性能
类继承的缺点
- 超类改变,子类要跟着改变,违反了“开——闭”原则
- 不能动态改变方法实现,不能在运行时改变由父类继承来的实现
- 破坏原有封装,因为基类向子类暴露了实现细节
- 继承会导致类的爆炸
因此在选择是继承还是组合的问题上,avalon倾向组合。组合的使用范例就是CSS,因此也有了ms-important的诞生。
而ms-important就相当于CSS的important语句,强制这个区域使用此ViewModel,不再往上查找同名属性或方法!
另,为了避免未经处理的原始模板内容在页面载入时在页面中一闪而过,我们可以使用以下样式(详见这里):
.ms-controller,.ms-important,[ms-controller],[ms-important]{ visibility: hidden; }
忽略扫描绑定(ms-skip)
这是ms-skip负责。只要元素定义了这个属性,无论它的值是什么,它都不会扫描其他属性及它的子孙节点了。
<div ms-controller="test" ms-skip> <p ms-repeat-num="cd" ms-attr-name="num" ms-data-xxx="$index"> {{$index}} - {{num}} </p> A:<div ms-each="arr">{{yy}}</div> </div>
avalon作用域:
ms-controller
子节点如果找不到表达式可以往父级上寻找
ms-important
子节点如果找不到表达,也不会往父级上寻找
ms-skip
此作用域下的表达式不工作