和我一起学习avalon(持续更新)

avalon的一个显著优点是它将视图与业务逻辑完全分离开来。若不用avalon的话,举个例子,当我们从后台获取数据后,通常还要自行对数据通过jquery等方式对数据进行处理,然后通过相应调整使该数据在DOM显示出来。而当使用了avalon后,对数据的操作和DOM的展示就可以很好的分离开来,通过VM实现对数据的操作,通过DOM实现数据的展示,然后对数据的操作会通过AVALON的库动态的传递到DOM,动态修改DOM展示内容。

1.vm的定义

该模型通过avalon.define方式进行定义,简称vm,avalon中用户定义的所有vm都会在avalon.vmodels中存储,因此为了方便获取,每个vm都通过$id来进行标识。ms-controller用来说明对于该vm的调用以及调用后的作用域。


Hello, {{name}}



说明想要在标题h1中调用$id为hello的vm

该模型定以后规定不许再添加新属性和方法,但可以添加子属性。比如以下是错误的添加属性方法。

var vm = avalon.define({
    $id:   "test",
    test1: "点击测试按钮没反应 绑定失败";
});
vm.one = function() {//不能再追加此方法
    vm.test1 = "绑定成功";
};
以下为正确的添加子属性方法

var vm = avalon.define({
    $id:   "test",
    placehoder: {}
});
setTimeout(function(){
   vm.placehoder = {//我们必须要通过 = ,直接添加一个对象来 添加子属性, 不能
      aaa: 1,      //vm.placehoder.aaa =1; vm.placehoder.bbb = 2这个分散地添加子属性
      bbb: 2      
   }
}, 1000)

其中placehoder是预先初始化已经定义好的,因此,可以通过该对象来添加子属性。

对vm进行定义=除了以上代码,还可以使用下面的形式

avalon.define("blog", function(vm){
    vm.subject = "Blog Title";
    vm.author = "张三";
    vm.publish_date = new Date('2014/3/15');
    vm.comment_count = 0;
    vm.content = "

这是一个测试的博客

" +
        "

这是内容 1

" +
        "

这是内容 2

" +
        "

这是内容 3

" +
        "

这是内容 4

"
        ;
});

2.在MVVM中vm(view model)、view和model

在该框架中,model其实就是所分析的数据对象,通常从数据库映射而来。view‘就是所显示的用户界面,本人理解,就是DOM方面的展示。而view model则是view与model间的桥梁,由于数据库很难直接跟网页控件相联系,所以需要VM在中间来指明view所对应的model。

3. 对ms-duplex属性的理解

在第1部分我们提到,通过avalon,可以将对数据的操作动态的传递到DOM,动态修改DOM展示内容,ms-duplex便是该功能实现所需的重要属性。举一个例子

<html>
    <head>
        <title>Avalon by RubyLouvretitle>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="avalon.js" >script>
  
        <script>
   avalon.define({
        $id: "test",
        string: "xxx",
        bool: true,
        number: 100,
        object: {
            aaa: "aaa",
            bbb: "bbb"
        }
    })
        script>
    head>
    <body>
        <div ms-controller="test">
            <input ms-duplex="string">{{string}}
            <input ms-duplex="bool" type="radio">{{bool}}
            <input ms-duplex="number" >{{number}}
            <ul>
                <li ms-repeat="object">{{$key}} --> {{$val}}li>
            ul>
        div>
    body>
html>
< input   ms-duplex = "string" >{{string}}部分,ms-duplex的作用,就是将该input控件中的value值重新赋给VM中的string(通过ms-duplex="string"来指定),作为string的新值,覆盖原来的XXX.此时{{string}}中显示的内容动态变为input控件输入的string对象的新值,而非XXX.在这里读者可能会问,avalon框架的一个特性不就是动态更新页面吗,即使不适用ms-duplex也可以做到通过input控件中的值value更新vm中的对象值进而动态更改视图显示啊,恩~这么说吧,如果不使用ms-duplex,则需要在input控件内将value值录入后一次性通过click等事件以及在VM中定义的函数进行关联,从而提交value,从而更新vm中的对象,而若使用了ms-duplex,则在控件中每输入一个字符,该字符就动态更新vm中的个对象,再输入一个字符,再使用控件中的value动态更新vm中的对象,无需再在VM中定义功能为修改VM对象值的函数,也不用一定要死板的需要全部输入完后通过事件来提交所更改的值。

4.有关于监控数组的代码1(注释部分为本人理解,在该部分目前由于本人为初学阶段,可能很多关于功能的理解并不正确,见谅)


   
        Avalon by RubyLouvre
       
       
  
   

 
   


            

               
  • 数组的第{{$index+1}}个元素为{{el}}

  •        

对数组进行push操作,并回车
           
       


           
       



 

5.有关数组监控的代码2


   
        Avalon by RubyLouvre
       
       
     

 
 


        示例二
       


           
           
       


       
           
               
                   
                   
                   
               
           
       
{{el.name}}{{el.size}}{{el.date}}

   


 

6.计算属性$computed

计算属性的作用是通过其他两个或多个监控属性计算而得到一个新的值。想要通过计算属性获取值的对象必须要含有set和get对象。

通过以下这个例子来介绍计算属性的使用方法

  

 avalon.define({ 

            $id: "test", 
            firstName: "司徒", 
            lastName: "正美", 
            name:{ //name即为监控属性,一个包含set或get的对象
                    set: function(val) {//里面必须用this而不能使用vm,问什么?我也不知道。。。。,val值为vm中所定义的对象firstName与lastName相加所得字符串
                        var array = (val || "").split(" ");//array为val或者“”通过“”划分后所得字符串数组
                        this.firstName = array[0] || ""; 
                        this.lastName = array[1] || ""; 
                    }, 
                    get: function() { 
                        return this.firstName + " " + this.lastName;,//通过该段代码指定fullName的值为this.firstName + " " + this.lastName                    } 
            } 
        }) 
            } 


7.非监控属性

非监控属性前面加$符号,如$id,$用户自定义属性名。非监控属性与监控属性的区别是对非监控属性值的更改不会动态在视图上同步出来。如以下代码

<html>
 
<head>
    <title>unobservabletitle>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <script src="avalon.js">script>
    <script>
        var vm = avalon.define({
            $id: "test",
            $aaa: "sss",
            $skipArray: ["bbb", "ccc"],
            aaa: 111,
            bbb: 222,
            ccc: 333,
            fn: function() {
                return "函数"
            },
            click: function() {
                vm.$aaa = vm.aaa = vm.bbb = vm.ccc = "change"
                vm.fn = function() {
                    return "----------"
                }
            }
        })
    script>
head>
 
<body ms-controller="test">
    <p>{{$aaa}}p>
    <p>{{aaa}}p>
    <p>{{bbb}}p>
    <p>{{ccc}}p>
    <p>{{fn()}}p>
    <button type="button" ms-click="click">点我button>
body>
 
html>

8、ms-class

avalon中对于标签的类的定义使用ms-class="类名:表达式",其中“:表达式”部分可写可不写,若表达式为true,则标签按照代码指定为指定类,否则相当于没有该段指定类的代码,为之前的默认类。,而除了通过ms-class指定类,还可通过ms-class-1、ms-class-2.....等也可实现对类的指定。当一个标签需要在不同情况下指定不同类,就可以同时使用ms-class、ms-class-1等来实现。不可以在一个标签内使用两次ms-class。代码实例如下:

<body ms-controller="ms-class">
    <div class="test" ms-class="aaa:toggle" ms-click="click">点我div>


  • :
    {{el.name}}:{{el.value}}


body>

对类指定后,则该标签内容在视图显示格式为对应的css所定义的.类名的格式

9、avalon作用域

为了实现不同人员的相互协作,每个人负责不同的avalon视图模型的编写是理所当然的,那么在多个视图模型存在的情况下,我们必然会涉及到对不同视图模型的作用域的定义,即该模型在视图代码的何处生效。

负责VM作用域定义的属性有三个:ms-controller,ms-important,ms-skip

其中ms-controller和ms-important类似,唯一的区别就是当ms-controller所指定区域的html代码含有该VM未定义的对象时,该html代码可向上寻找,寻找上一级即作用域包含了包含该区域的VM,而ms-important则不会向上寻找。为了更好的说明,我们来举一个例子:

一段代码,其VM的定义代码如下:

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()  
})
html代码如下:

<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>

其在浏览器的显示结果为

liger : green
sphinx : red
dragon : red
sirenia : {{color}}
说明在最后一个标签处,名为DDD的VM中没有color对象,则直接显示出{{color}},而倒数第二个标签,当CCC中无color对象时,会向上寻找到上一级的名为BBB的VM,显示出该VM种的color值。

10.avalon过滤器

avalon中定义过滤器的方式为:avalon.filters.过滤器名=function(第一个参数,其余参数...){函数定义}.代码示例

avalon.filters.haha = function(str) { //用法: {{aaa|haha}}
    return str + "哈哈"
}


你可能感兴趣的:(js)