avalon笔记
★无聊逛逛看看已经解决的问题和一些案例:https://github.com/RubyLouvre/avalon/issues?q=is%3Aissue+is%3Aclosed
avalon各版本:http://www.bootcdn.cn/avalon.js/
目前最新1.5.8下载:avalon.shim.min
$id //监听区域的ID $skipArray $watch $event //事件里内置的 event对象 vm.$model //获取到 视图模块对象中的所有属性和方法除了带有$符号的,返回一个对象。 $outer $computed //计算属性 感觉没什么用2.0的时候废除了 avalon.vmodels // 一些全局$属性 遍历 ms-repeat $key, $val, $index, $last, $first, $remove
avalon比jquery优秀之处就在于,avalon不用去获取过多的DOM节点如图:

avalon作用域:
ms-controller
子节点如果找不到表达式可以往父级上寻找
ms-important
子节点如果找不到表达,也不会往父级上寻找
ms-skip
此作用域下的表达式不工作
avalon.ready
avalon.ready(function(){ //HTML的DOM节点加载完就可以运行代码 //1.4.*可以使用新旧两种风格定义VM,推荐使用以下风格 var vm=avalon.define({ //avalon代码 }); avalon.scan(document.body); //代码的最后扫描工作 });
查看版本号
avalon.version
遮丑
.ms-controller,.ms-important,[ms-controller],[ms-important]{ visibility: hidden; } <div ms-controller="test" class="ms-controller">{{aaa}}</div>
————————————————————————————————–
表达式: 可以理解成将数据打印到页面上,代码如下:
默认{{value}}
遇到复杂一点的数据结构,就像以往获取js方法一样使用如:
obj:[{name:'陈陈',age:123}] <p>{{obj[0].name}}</p>
配置config
也可以自定义表达式符号
avalon.config({ interpolate:['[[',']]'] });
结果[[value]]
//正式上线时,关闭控制台的错误提示 avalon.config({ debug: false })
为vm添加属性、和方法
//为vm添加属性、和方法之前必须先在vm中声明好属性名和类型 var vm=define({ $id:'ceshi', fun:avalon.noop(), //定义一个空的function,也可以这么写 fun:function(){},说明fun属性名是一个function类型 name:'', //声明一个name属性名,类型为字符串 arr:[] }); //添加方法 vm.fun=function(){ //代码 } //添加属性 vm.name='陈陈'; //添加属性 vm.arr=[1,2];
其实表达式{{value}}的原型调用的是ms-test
ms-test 只能将纯文本打印到页面上,
表达式还有过滤器功能如:
{{value | html}}
也就是将字符串中带有html标签解析出来,如下代码:

ms-value对表单元素value的设置

—————————————————————————————–
过滤器过滤器只能支持{{}}这种表达式
JS代码:

HTML代码:

输出内容:

也可以多个过滤器使用

自定义过滤器
avalon.filters.xxx=function(str,参数1,参数2){ return{ 'jpy':'日元' }[str] } avalon.ready(function(){ });
调用:{{"jpy" | xxx}} //日元
ms-duplex双向数据绑定 (它只绑定在表单元素,input, textarea, select,其实ms-duplex设置的值也就是表单元素的value值)
<input type="text" ms-duplex="username"> <input type="password" ms-duplex="password"> <textarea ms-duplex="profile"></textarea>
要求以上3种的ms-duplex值是字符串,可以使用ms-duplex-string代替,如图:

ms-duplex的值要求type=”radio”类型是布尔值,可以使用ms-duplex-boolean代替,如图:

ms-duplex的值要求type=”checkbox”类型是数组,可以使用ms-duplex-checked代替,如图:

<select ms-duplex=”hotel”>单选类型 ms-duplex的值要求为字符串
<select ms-duplex=”hotel” multiple=”true”>加了多选属性ms-duplex的值要求为数组
multiple=”true” //avalon把自定义的hotel的值视为数组 如果是false或者不写时 avalon视为字符串
多选一:以下指令只能用于type=”radio”
ms-duplex-text //值是字符串

ms-duplex-boolean //值是布尔,适用于布尔值的逻辑判断

禁用双向数据绑定

显示隐藏 ms-visible ms-if
ms-visible 的隐藏是通过css来控制的

ms-if 的隐藏是通过直接删除dom来 实现效果 以上的例子可以直接把ms-visible改成ms-if
数据缓存 类似$().data()
设置方法: ms-data-自定义名字=“属性名”

获取方法:需要注意数组和对象

元素属性 添加 修改类似 $().attr() .prop()
当value为undefined, null, false,会移除此属性,否则会添加此属性
主要介绍这些例子的使用
ms-attr-disabled
ms-attr-readonly
ms-duplex-string
ms-attr-selected
ms-attr-checked
ms-attr-id
ms-attr-name
ms-attr-src
ms-attr-title
ms-attr-data
ms-attr-href //推荐这种写法
ms-class //这个是重点经常用到,ms-class-1 ms-class-2 命名的先后顺序跟序号有关
还可以这么写 ms-class-diy=”true” //靠布尔值判断是否添加diy样式名 1.5.x废除了
ms-class=”hover:true” //现在推荐这种写法,布尔值判断是否添加hover类样式名
ms-class=”hover:hover_name===1″ //条件判断当hover_name等于1时条件满足也为true
直接看例子:https://sdeno.com/zp/ava/av3.html
属性分为两大块,默认在vm中设置的属性都是监听属性,如果不想监听请使用,这样值就算被修改了永远都不会跟试图同步,在试图中永远显示初始值不会被修改。
$skipArray //$skipArray: [“a”] ,$skipArray 放在要设置非监听属性的同层中
$ //为属性添加,如 $a
:: //直接在表达式中添加 {{::a}},ms-attr-value=”::aaa”,如果不想让视图同步更新但是又希望值发生变化后回调就使用它
1,上面3种方法的共同效果是就算vm中的a属性值改变了,视图中的值是不会同步更新的,但是a的值是可以改变的。
2,使用$skipArray和$ 方法,在$watch监听a属性是不会触发的,但是用::就算视图不同步更新还是能触发$watch回调的因为值发生改变了。
ms-duplex 2.0 其实也就是细化分类了ms-duplex种类

ms-duplex-string
ms-duplex-number
ms-duplex-boolean
ms-duplex-checked
ms-data-duplex-observe //1.5x废除
// data-duplex-observe="true"是可以动态判断是否要视图和数据同步更新,现在1.5.x废除了, 如果你想用$skipArray动态添加是没有效果的, 现在要实现同样的功能只能使用拦截器了, var vm = avalon.define({ $id: "test", con:'11', }); avalon.duplexHooks.add100={ get:function(val,e){ if(/data-duplex-observe=\"false\"/i.test(e.element.outerHTML)){ return vm.con; }else{ return val; } } }; <input type="text" ms-duplex-string-add100="con" data-duplex-observe="false"> //自定义一个拦截器名字为add100,为这个拦截器添加判断,在用户手动输入内容时如果发现有data-duplex-observe="false"就禁止同步视图。
data-duplex-changed //值发生变化就会触发,并且能记录新值,跟$watch功能类似。此指令只能跟ms-duplex配合使用,也就是ms-duplex存在的地方才能用它
data-duplex-focus //1.5x和最新的1.4.x已经都不支持了,用JQ的focus代替吧
data-duplex-event //填写事件名称,相应的事件触发了 页面上才会跟数据同步
//1.4.x默认情况下,使用ms-duplex只要用户输入的值变化视图中就会同步数据。如果不希望时时更新同步数据,想依靠用户事件来触发视图数据更新可以使用data-duplex-event data-duplex-event="click" //只有点击时候才能更新视图数据 data-duplex-event="blur" //只有失去焦点时才更新视图数据 1.4.x的data-duplex-event只支持change, click, mouseover, mouseout, focus, blur //1.5.x中 data-duplex-event="change" 只能这么使用,效果跟blur一样当失去焦点才会触发,如果想和1.4.x功能一样用jquery配合吧
以上指令案例:https://sdeno.com/zp/ava/av4.html
ms-duplex的回调data-duplex-changed
当表单元素上绑定着ms-duplex时,值在变化时需要触发回调就使用data-duplex-changed=”fn”
fn:function(newvalue,event){ 当前的新值,event对象(例如能获取当前绑定ms-duplex的dom对象) //回调需要执行的代码 }
avalonjs插件封装 duplexHooks拦截器 基于ms-duplex-*下扩展的
duplexHooks案例:https://sdeno.com/zp/ava/duplexHooks.html
并且一个ms-duplex是可以带N多拦截器的,如ms-duplex-number-string-diy1-diy2=’a’
avalon.ready(function(){ var vm=avalon.define({ $id:'ceshi', a:'ee' }); avalon.scan(); }); avalon.duplexHooks.mylimit={ get:function(str,data){ var limit= parseFloat($(data.element).attr('data-duplex-mylimit')) ; alert(str.length); if(str.length>limit){ return data.element.value=$(data.element).val().slice(0,limit); } return str; //return str是负责输出当前的同步信息,也就是ms-duplex的功能 } } <div ms-duplex-number-string-diy1-diy2="a">{{a}}</div>
ms-css
ms-css-width="num" //如果num只写数字,默认自动加px ms-css-width="{{num}}%" //{{num}}px ms-css-font-size="num2"
事件绑定
<div ms-click-1="fn1" ms-click-3="fn3" ms-click-2="fn2"></div> 执行顺序是 fn1 fn3 fn2 跟序号无关
循环 遍历
ms-each 貌似废除了
ms-with废弃
ms-repeat //官方推荐
数据是数组时可以使用:$index,$last,$first,$remove
数据是对象时可以使用:$key, $val,$remove ,$index//1.5.x对象也添加$index遍历了
$outer: 得到外围循环的那个元素。(这个不好理解直接看例子)
<ul> <li ms-repeat="arr" ms-click="click(el,$event)"> {{$index}}--{{el}}--此值是否为最后一个值:{{$last}} --此值是否为最前一个值: {{$first}} </li> </ul>
<ul> <li ms-repeat="obj" ms-click="click2($key,$val,$event)">{{$key}}--{{$val}}</li> </ul>
arr_arr:[
['a','b','c'],
['aa','bb','cc'],
['aaa','bbb','ccc']
]
<table border="1">
<tr ms-repeat="arr_arr">
<td ms-repeat-child="el">{{avalon.log($outer)}}--{{child}}</td> //el表示的是数组['a','b','c'],['aa','bb','cc']...
</tr>
</table>
不管是对象还是数组默认输出{{el}}或者{{$val}} 都会把全部值输出出来,如果只想输出指定的下标,在遍历的同时要进行判断如:
//数组 <tr ms-repeat="arr"> <td ms-repeat-child="el" ms-if-loop="$index===1">{{child}}----<a ms-click="$remove">x</a></td> //默认其他下标隐藏,只显示下标为1的元素 </tr> //对象 <tr ms-repeat="arr"> <td ms-repeat="el" ms-if-loop="$index==='name'">{{el.name}}</td> //默认其他下标隐藏,只显示下标为name的元素 </tr> 如果数据是对象的话可以通过data-with-sorted="im"返回数组来指定要显示的属性名 im:function(){ return ['name','age'] //只显示属性名是name和age的值 } //遇到复杂的就传一个参数判断 ms-if-loop="toggle($index,$events)"
数据更新
arr:['aa','bb'] vm.arr.set(0, 'cc') //['cc','bb'] arr1:[{text:'aa'},{text:'bb'}] vm.arr1[0].text='cc' // [{text:'cc'},{text:'bb'}] //如果要更新对象属性名称,只能是重写对象了 obj:{name:'陈陈',age:27} vm.obj={name11:'陈陈',age11:27};
数据增、删、改、查后触发的回调(重要)
一般是ms-repeat遍历插入DOM成功后需要回调就可以使用data-repeat-rendered
back_fn:function(status){ console.log(this); console.log(status); } data-repeat-rendered="back_fn" //负责监听数组,返回状态有add,index,set,del,move,clear 描述: 1,第一次将数组里的内容一个个遍历插入到页面,并渲染完成时,默认就会回调状态是add,可以判断利用这个add状态的回调去执行我们的其他业务。 2,为数组添加新元素后会再次渲染页面时会回调一个add,之后数组的索引发生改变紧接返回一个index,可以利用这个index判断数组是否增、删过。 3,修改数组时,返回set 4,删除时,返回del 5,重新排序时,返回move,索引也会改变在紧接返回index 6,清除数组所有内容时,返回clear vm.arr.removeAll() removeAll()//是avalon自己封装的 -------------------------------------------------------------------------------- data-repeat-rendered="obj" //负责监听对象,返回状态有append,set,del,move,clear 描述: 1,第一次把对象里的数据更新到页面完成后,返回的状态是append,其余跟操作数组一样 (具体尝试监听status状态) ---------------------------------------------------------------------------------- im:function(){ return ['你','他1']; } data-with-sorted="im" //绑定,并返回一个数组,数组里面的元素填写的是对象的属性名,返回的数组的长度和排序也决定着修改,遍历对象数据的内容。 具体查看视频:http://www.imooc.com/video/6934 3-4 回调绑定属性
ms-if-loop
ms-if-loop=””和ms-if=””加载元素上默认此元素都会在删除,达到隐藏的效果。但是ms-if执行的优先权比ms-if-loop还要大,
所以在和ms-repeat配合使用时,要使用ms-if-loop,因为ms-if执行的优先权也大于ms-repeat
直接看例子:demo1
在看一例子:
arr:[{name:'小李',age:25},{name:'小三',age:27},{name:'小四',age:28}] <table> <tr ms-repeat="arr"> <td ms-repeat="el" ms-if-loop="$key==='name'" >{{el.name}}</td> //如果换成ms-if就没有效果了,因为优先权的问题,要保证数据显示了删除DOM </tr> </table>
数组长度
数组的长度使用 arr.size()去获取
内置操作数组方法
主要不是放在以$开头,和$skipAarray数组中的数据都是会被监听的,被监听的数组有很多方法可以去操作。 在avalon中被重新方法有(也就是在已有原生JS的方法基础上重新): push, //末尾添加元素 pop, //删除最后一个元素 shift, //删除最前一个元素 unshift , //添加元素在最前 splice, //有删除,增加,替换功能 sort, //自然顺序排序 reverse //倒序 新增方法有: pushAll, //1.4.7.2以后 废除 slice, // 返回筛选后的数组, vm.arr.slice(2,4),选取索引为2和4之间的内容,包括2索引内容,但不包括4索引内容,返回组成的一个数组 remove , //根据内容删除元素 (注意内容的类型) removeAt, //根据索引删除元素 removeAll , //删除多个 vm.arr.removeAll([2,3]) ; clear, //清空全部 ensure, //ensure,检查要插入的内容数组是否存在,不存在才push进数组 set // 根据索引修改内容 vm.arr.set(0,'wo')
模板
从外部引入一个页面 ,是利用ajax方法引入,并且是get方式 (avalon没有提供ajax功能需要的话使用jquery)
avalon.define({ $id: "test", tem:'tem1' }) <div ms-include-src="tem+'.html'"></div> 文件名tem1.html <div ms-include-src="{{tem}}.html"></div> 缓存:avalon.templateCache avalon.templateCache['diy']='<em>fffff</em>'; avalon.define({ $id: "test", tem:'diy' }) <div ms-include-src="tem"></div>
加载模板成功后的回调
data-include-loaded="fn" //当我们使用ms-include-src加载模板成功后,需要在模板基础上追加内容可以使用data-include-loaded fn:function(data){ //data获取到的是加载模板的内容 return data+'可以在模板基础上追加内容'; } <div ms-include-src="tem" data-include-loaded="fn"></div> data-include-rendered="fn" 如果仅仅只是回调,不需要获取加载成功后的模板内容可以使用此属性 fn:function(){ console.log(11); } <div ms-include-src="tem" data-include-rendered="fn"></div> data-include-replace //默认情况在某div中使用ms-include-src加载模板后,内容都插入到此div里面 //如果使用data-include-replace="true",模板将会替换此div,并在div的位置上插入内容。 <div ms-include-src="tem" data-include-replace="true"></div>
$watch
VM属性的第一层才有$watch
注意属性名如果$开头,或者是存放在$skipArray:[‘value’]数组中,这样的属性的值就不会被监听了。
1.4.x的写发是 vm.arr.$watch(‘length’,fn); 1.5.x改成 vm.$watch(‘arr.length’,fn) //监听长度发生变化回调
1.4.x的写发是 vm.obj.obj2.$watch(‘obj3’,fn); 1.5.x改成 vm.$watch(‘obj.obj2.obj3’,fn) //监听内容变化回调
★本人测试如果你遇到复杂点的数据结构你还是要用1.4.x的写法才能回调成功,再说1.5.x也兼容1.4.x的写法例如:
arr:[['ni11','wo11','ta11',{name:'chen',age:25}],['ni22','wo22','ta22','haha22'],['ni33','wo33','ta33','haha33']] click1:function(){ vm.arr[0][3].age=24; //监听对象中age数据变化 } vm.arr[0][3].$watch("age",function(newvalue,oldvalue){ //成功回调 document.title=1; }); vm.$watch("arr.*.age",function(newvalue,oldvalue){ //失败 document.title=1; }); vm.$watch("arr[0][3].age",function(newvalue,oldvalue){ //失败 document.title=1; });
有变动关注:http://avalonjs.github.io/
var vm=avalon.define({ $id:'ceshi', value1:'测试', value2:'测试', $skipArray:['value1','value2'], obj:{ obj1:{ obj2:'内容', $skipArray:['obj2'] } } });
简单属性值的监听,只要值变化就回调 var vm=avalon.define({ $id:'ceshi', value:'内容' }); vm.$watch('value',function(newvalue,oldvalue){ console.log(newvalue+'---'+oldvalue); }); ------------------------------------------- 数组的监听只有长度变化时候回调 var vm=avalon.define({ $id:'ceshi', arr:[1,2], click:function(){ vm.arr.push(' '); } }); vm.arr.$watch('length',function(newlength,oldlength){ *注意1.4.X版本监听数组长度变化用'length' //新的长度 和 旧的长度 }); 1.4.X没有监听数组内容变化,根据已有的功能可以自己写一个监听数组内容变化的回调 var vm=avalon.define({ $id:'ceshi', arr:[1,2], set_status:false, fn:function(){ vm.old_arr=vm.arr+''; vm.arr.set(0,'内容1'); // vm.arr.push('加内容'); if( vm.set_status ){ vm.arr.push(' '); } }, back_fn:function(status){ if( status=='set' ){ vm.set_status=true; } }, }); vm.arr.$watch('length',function(newvalue,oldvalue){ if(vm.set_status){ var new_arr=[]; for(var i=0;i<newvalue;i++){ new_arr[i]=vm.arr[i]; }; console.log('旧数组:'+vm.old_arr+'---'+'新数组:'+new_arr); document.title=vm.old_arr+'---'+new_arr; }else{ console.log(newvalue+'--'+oldvalue); } }); <button ms-click="fn">点我</button> 1.5.X增加了监听数组内容变化触发回调的功能。 vm.$watch('arr.*',function(newvalue,oldvalue){ document.title=newvalue+'--'+oldvalue; }); ------------------------------------------- 对象的监听,只要值变化就回调 var vm=avalon.define({ $id:'ceshi', obj:{ obj1:{ obj2:'内容' } }, }); vm.obj.obj1.$watch('obj2',function(newvalue,oldvalue){ //1.4.X的写法 //newvalue,oldvalue }); vm.$watch('obj.obj1.obj2',function(newvalue,oldvalue){ // 1.5.x的写法 //newvalue,oldvalue }); 或者 vm.$watch('obj.*.obj2',function(newvalue,oldvalue){ // 1.5.x的写法,不管中间各了多少层都能监听到obj2的值变化而触发 //newvalue,oldvalue }); --------------------------------------------- $all // 监听所有同级属性 vm.$watch('$all',function(name,newvalue,oldvalue){ //1.4.X监听的属性名,修改后的值,修改前的值; 1.5.X把$all改成* console.log(name,newvalue,oldvalue); }); 上面的例子,如果遇到复杂点的对象内容修改后就不能监听到了,例如: obj:{ obj1:{ obj2:'内容', //obj2内容如果修改了上面例子是监听不到的 obj3:'内容2' } }, 如果想监听obj2同级的所有属性,那要这样写: 在线案例 vm.obj.obj1.$watch('$all',function(name,newvalue,oldvalue){ 1.4.x的写法 console.log(name,newvalue,oldvalue); //avalon.log(avalon.slice(arguments)); // ["aaa", 2, 111] // ["bbb", 3, 222] });
$unwatch不常用 1.5.X也废除了,如果需要移除$unwatch,就这么使用:
var unwatch = vm.$watch("array.*", function(a, b) { expect(a).to.be(6) expect(b).to.be(2) }) unwatch() //移除当前$watch回调
$fire //如果想要重新监听 $开头的属性和 $skipArray名单中的属性监控就用它
VM属性的第一层才有$fire
$fire案例:https://sdeno.com/zp/ava/av7.html
var vm=avalon.define({ $id:'ceshi', click:function(){ var old= vm['obj'].obj1.obj2; vm.$fire(vm.obj.obj1,'要修改的值',old); //监听的属性名,修改的新值,旧值 }, obj:{ obj1:{ obj2:'内容', obj3:'内容1', $skipArray:['obj2'] //只有把禁止监听的属性名和它放在同一层才有效果 } } }); vm.$watch('$all',function(name,newvalue,oldvalue){ console.log(name,newvalue,oldvalue); //Object {obj2: "内容",'''} "112" "内容" });
模块之间的通讯—-$fire
描述:也就是定义好的ms-controller之间可以传递属性或者方法,主要靠down!,up!,all!
down!,up! //必须要等dom加载完成后执行,同辈的模块不传递,并且只传递给自己父辈模块和后代模块。
all! //不需要等带dom加载完,传递所有模块,包括同辈模块
在线案例:https://sdeno.com/zp/ava/av9.html
深拷贝和浅拷贝类似JQ的$.extend
avalon.mix //貌似有点问题,https://github.com/RubyLouvre/avalon/issues/509
如果需要还是用JQ吧
var aa = avalon.mix(true, [], vm.$model.arr)
自定义指令(绑定)directive 基于ms-*下扩展的 (它可以取代ms-duplex又一个新的双向数据绑定指令)
var vm=avalon.define({ $id:'ceshi', value:187 }); avalon.directive('diy',{ //页面默认加载都会执行init和update各一次 init:function(e){ console.log(e); //查看下 avalon(e.element).addClass('fff'); console.log(this); //这里的this包括了 inti函数和update函数 e.meimei='妹妹'; }, update:function(newvalue, oldValue){ //功能上类似$watch,如果监听的value值发生变化,update会再次被执行回调一次 console.log(this); //这里的this是,其实是init传过来的e对象,查看下是否有meimei的属性值为妹妹咯 } }); <button ms-diy="value" ms-click="click">点</button>
avalon.scan()后的回调
avalon1.5.6 添加扫描后的回调 在目标DIV加上ms-controller="test", $id为test的VM监听一个"ms-scan-end"回调 vm.$watch("ms-scan-end", function(div){ //div为绑定的元素 })
动画effect (avalon居然还提供动画,现在avalon是越来越强大了,简单动画可以使用,复杂的还是使用JQ已经JQ相关插件吧,毕竟avalon主要是处理双向数据绑定而存在的)
作者提供的实例: https://github.com/RubyLouvre/avalon/issues/897#issuecomment-128355485
avalon的动画触发条件基本都是插入DOM或者删除、隐藏DOM时候才能加上动画效果
//js动画演示 avalon.effect("expand", { //ms-effect="expand" leave: function (elem, done) { $(elem).hide(300,done)// 此DOM隐藏或者移除时候的动画写这里,并且动画结束后要回调去执行这个done函数,不然就不会有afterLeave的回调了 }, enter: function (elem, done) { $(elem).show(300, done) //此DOM显示或者插入时候的动画写这里,并且动画结束后要回调去执行这个done函数,不然就不会有afterLeave的回调了 }, beforeLeave: function () {//在动画前做一些事 console.log("beforeLeave") }, afterLeave: function () { console.log("afterLeave")//在动画后做一些事,这里要执行的话,动画执行完后必须要回调一下leave和enter中的done函数,不然这里是不会执行的 }, cancelLeave: function () { //暂时不懂干嘛的 } }) <div ms-click="hide" class="jsani" ms-effect="expand">点我执行动画</div> avalon的动画触发条件基本都是插入DOM或者删除、隐藏DOM时候才能加上动画效果, effect代码部署完成,但是要触发effect对象需要以下方法: ms-if //只有enter动画; ms-include //同时有enter, leave动画; ms-visible //视元素的隐藏显示情况采用enter或leave动画; ms-repeat //视元素的插入或移除情况,使用enter或leave动画,此外还有move动画; 或者靠JS增、删DOM来触发effect对象动画,如: del: function () { avalon.effect.remove(this, this.parentNode, function (el) { //删除this.parentNode元素里面的this元素 console.log(el); //这里的el是删除元素的dom,并且元素删除成功后才回调此处代码 }) }, add: function () { avalon.effect.append(el, document.body, function (el) { //在元素document.body的内部后面加上el元素 console.log(el) }) }, add2: function () { avalon.effect.before(el, document.body, function (el) { //在元素document.body的内部前面加上el元素 console.log(el) }) } 以上的执行顺序和步骤是:beforeLeave > leave || enter > afterLeave > avalon.effect.append || avalon.effect.before || avalon.effect.remove的回调
自定义UI组件 avalon.component (要配合CSS和JS用,也就是自定义好div结构,用的时候插入就行直接就有效果了)
avalon.component('ms:diy',{ $init:function(event,dom){ console.log(event,dom); //优先执行,起到初始化变量的作用 }, $ready: function(event,dom) { //DOM加载完成后,执行 }, $replace:true, //布尔值为真,会将<ms:diy></ms:diy>元素会被$template里面的元素覆盖成;如果为假,就在<ms:diy></ms:diy>里面插入$template模板 $template:'<input type="text" ms-duplex="text">' //要在<ms:diy></ms:diy>中插入的模板,默认解析html标签 }); <ms:diy></ms:diy>
具体教程:http://avalonjs.github.io/#tutorial/component/index.html
1.5.x禁用异步
在1.5.x中VM的每个属性的值都是异步更新视图中的数据的,在自定义拦截器时候如果因为异步问题可以禁用异步如:
avalon.config({ async: false })
———————————————————————————————————————————
avalon 1.5.6 新增已经修改
https://github.com/RubyLouvre/avalon/tree/1.5
正美博客1.5.Xhttp://www.cnblogs.com/rubylouvre/p/4783966.html
1,添加动画指令 ms-effect avalon.effect http://avalonjs.github.io/#tutorial/directives/effect.html
2,添加基于自定义标签的组件指令 http://avalonjs.github.io/#tutorial/component/index.html
3,$watch方法和解除监听 http://avalonjs.github.io/#tutorial/concepts/$watch.html
4,计算属性全部移动$computed对象上集中定义 http://avalonjs.github.io/#tutorial/concepts/computed.html
5,avalon1.5新添加的API,avalon.directive, 用于快速创建一种全新的指令! http://avalonjs.github.io/#tutorial/directives/custom.html
6,废掉avalon.define的旧风格定义,只支持新风格
7,废掉data-duplex-observe辅助指令
8,废掉ms-widget 详看component/pager/avalon.pager.js 是怎么将原来组件改成新组件的
9,添加$fire(“all!xxx”)的支持
10,configs 改名为 config
11,$extends 改名为 $extend
12,全新的parser
13,ms-scan-end 回调
———————————-avalon中的jQuery功能———————————————–
对于用惯jQuery来获取DOM来操作的也可以在avalon上使用,例如
获取当前对象的DOM
var vm=avalon.define({
$id:'ceshi',
click_ed:function(){
avalon(this).addClass('hover').width(300);
//在哪个DOM上绑定了click_ed这里的avalon(this)指的就是当前的它,跟操作JQ是一样的
}
});
<div ms-click="click_ed">me</div>
以下方法跟jquery用法一样,在avalon中要使用以下方法来操作dom就要把dom封装成avalon对象,例如:
avalon(dom).css()
绑定事件: bind() unbind()
样式: css() width() height() innerWidth() innerHeight() outerWidth() outerHeight() position() offset() offsetParent() scrollLeft() scrollTop() addClass() removeClass() hasClass() toggleClass()
元素属性 attr() val() data() removeData()
方法或属性 | 描述 |
---|---|
mix(a,b) | ★★★相当于jQuery.extend,参数个数不定,用于深浅拷贝属性,比如avalon.mix(a), avalon.mix(true, target, c, d) |
log(s) | 打印日志, 参数个数不定, 比如 avalon.log(a); avalon.log(a, b) |
isFunction(s) | 判定是否为函数,1.3.6新增 avalon.isFunction(alert) ==> true |
error(s) | 抛出异常,比如avalon.error(‘类型不正确’) |
ui | 一个对象,用于放置各种widget的构造器。大家在控制台下查看console.log(avalon.ui)就明白什么回事了。 |
vmodels | ★★★用于放置avalon.define(id, fn)产生的ViewModel。大家在控制台下查看console.log(avalon.vmodels)就明白什么回事了。 |
noop | 一个空函数 |
ready(fn) | ★★★domReady,将回调延迟到DOM树后才执行 avalon.ready(function(){alert(‘页面上的标签已经全部变成DOM对象’)}) |
oneObject(str | array, val?) | ★★★如果传入一个字符串则将它以逗号转换为一个字符串数组,否则一定要传字符串数组,第二个参数可选,为生成的对象的值。此方法是用于生成一个键名不一样,但键值都一样的对象。比如 avalon.oneObject(‘a,b,c,d’) ==> {a:1, b:1, c:1, d:1} |
type(obj) | ★★★返回传参的数据类型,值可能为array, date, object, json, number, string, null, undefined,比如 avalon.type(‘aaa’) ==> ‘string’ avalon.type(12345) ==> ‘number’ avalon.type(null) ==> ‘null’ avalon.type(void 0) ==> ‘undefined’ avalon.type(window) ==> ‘object’ avalon.type([1,2,3]) ==> ‘array’ |
isWindow(obj) | 判定是否为window对象 |
isPlainObject(obj) | 判定是否是一个朴素的javascript对象(Object),不是DOM对象,不是BOM对象,不是自定义类的实例 |
slice(obj, start?, end?) | 用于转换一个类数组对象为一个纯数组,后面两个为索引值,可以只取原对象的一部分元素,比如 avalon.slice(document.getElementsByTagName(‘p’), 10) avalon.slice(arguments) |
range(start, end, step) | 生成一个整数数组,功能与underscorejs或python的同名函数一致,比如 avalon.range(10) ==> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] avalon.range(1, 11) ==> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] avalon.range(0, 30, 5) ==> [0, 5, 10, 15, 20, 25] avalon.range(0, -10, -1) ==> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]avalon.range(0) ==> [] |
bind(el, type, fn, phase?) | 绑定事件,返回一个回调给你自行卸载,比如 avalon.bind(document.body, ‘keydown’, callback) |
unbind(el, type, fn, phase) | 卸载事件,比如 avalon.unbind(document.body, ‘keydown’, callback) |
each(obj,fn) | ★★★功能同jQuery.each, 都是索引值或键名在前,值或元素在后 |
avalon.define(id, factory) | ★★★定义一个ViewModel, 旧风格: avalon.define(‘test’, function(vm){ vm.aaa = 1}) 新风格: avalon.define({$id: ‘test’, aaa: 1}) id: 用来定义VM的$id属性 factory: 用来收集vm属性并初始化值,并且规定哪些可监控的,哪是需要计算的,哪些是不可监控的 |
scan(el?, vmodels?) | ★★★扫描DOM树,抽取绑定(el默认为DOM,vmodels默认为空数组 avalon默认在domReady时,从body开始扫描一次,以后自己动态添加了新内容,需要自己手动scan。 如果你的VM是定义在某个回调里面,如require回调,也需要自己手动扫描 |
define(id?, deps?, factory) | ●一个全局方法,用于定义AMD规范的JS模块 |
require(deps, callback) | ●一个全局方法,用于加载JS模块 |
css(node, name, value?) | 如果只有两个参数,读取元素的某个样式,三个参数时,设置元素某个样式; 在设置样式时,如果是长宽等计量属性,你可以直接传一个数值,框架会自动帮你添加px单位; 如果是取值时,你的第三个参数是true,它会帮你去掉单位,转换为纯数值 |
nextTick(fn) | 延迟执行某个函数,类似于setTimeout(fn, 0) |
contains(a, b) | 判定A元素包含B元素,比如 avalon.contains(document.documentElement, document.body) ==> true |
parseHTML(str) | 将一段字符串转换为文档碎片 |
innerHTML(node, str) | 对节点node进行innerHTML操作,在旧式IE下,head, table, td, tr, th等元素的innerHTML是只读,这个方法进行了兼容处理 |
clearHTML(node) | 清空元素的所有子节点 |
Array.remove(array, el) | 移除某个元素,成功返回true,失败返回false |
Array.removeAt(array, index) | 移除某个位置上的元素,成功返回true,失败返回false |
Array.ensure(array, el) | 只有数组不存在此元素时才添加它 |
http://avalonjs.github.io/#api.html
————————————avalon UI组件已经功能补全—————————————————–
avalon仅仅是双向数据绑定功能比较强大,但是缺少ajax、cookies、表单验证等等第三方插件其他的功能。
你想要的这里基本都满足:http://ued.qunar.com/oniui/index.html#!/widgets