avalonjs笔记

2015-4-6    分类: avalon.js笔记,前端资源

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节点如图:

jqava

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}}
默认{{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-text&html

 

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

ms-value

 

-----------------------------------------------------------------------------------------

过滤器过滤器只能支持{{}}这种表达式

JS代码:

guolvqi1

HTML代码:

guolvqi2

输出内容:

guolvqi3

也可以多个过滤器使用

guolvqi4

自定义过滤器

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代替,如图:

str_ms-duplex

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

bool_ms-duplex

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

checkbox_ms-duplex

 

<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 //值是字符串

radio_ms-duplex

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

ms-duplex-boolean

禁用双向数据绑定

ms-data-duplex-observe

 

 

显示隐藏 ms-visible     ms-if

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

ms_visible

 

ms-if 的隐藏是通过直接删除dom来 实现效果  以上的例子可以直接把ms-visible改成ms-if

 

 

数据缓存   类似$().data()

设置方法:  ms-data-自定义名字=“属性名”

ms_data

 

 

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

avalon_get_value

 

 

 元素属性 添加 修改类似 $().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://www.xgllseo.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

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://www.xgllseo.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://www.xgllseo.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://www.xgllseo.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://www.xgllseo.com/zp/ava/av9.html

avalon_note

 

深拷贝和浅拷贝类似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  新增已经修改

avalon1.5.x新增功能以及修改

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