avalon实现日期联动

前言

上一篇我们说了下Avalon的一些概念,以及一些主要特性,至于Avalon的一些基础教程,正美老师已经做了非常全面的讲述,参见:http://www.cnblogs.com/rubylouvre/p/3962848.html

以后我们将使用Avalon做几个实际的小例子,也是我在工作中使用中的东西,avalon的文档特别全,但是生产中使用的例子却非常少,所以我会在博客中多写些我工作中使用的例子。

这次先是一个日期联动组件,效果和源码请参照:http://runjs.cn/detail/vsuij302

这个简单的小组件能实现:1.默认三个下拉框选中的是当前的年月日。2.可自定义初始显示几年的数据。3.选择年和月的时候,可以自动判断日有多少天。4.当选择到1月31日时,切换成2月,自己定位到2月的最后一天,不会出错。

首先我们来看HTML部分

        <div ms-controller="dateCtrl">
            <select ms-duplex="year">
                <option  ms-repeat="yearArr">{{el}}</option>
            </select>
            
            <select ms-duplex="month">
                <option  ms-repeat="monthArr">{{el}}</option>
            </select>
            
            <select ms-duplex="day">
                <option  ms-repeat="dayArr">{{el}}</option>
            </select>
        </div>

HTML部分,第一首先定义了一个controller,然后是三个select下拉框,用于显示年、月、日;ms-duplex用于和VM中M层进行双向绑定,ms-repeat用于循环展示哪些年、哪些月、哪些日。

Avalon部分:

定义VM

var dateVM = avalon.define({
        $id : "dateCtrl",//- controller的id
        yearsAgo : 10,//- 展示多少年
        yearArr : [],//- 年的数组
        year : 1,//- 年,用于监听
        monthArr : [],//- 月的数组
        month : 1,//- 月,用于监听
        dayArr : [],//- 日的数组
        day : 1//- 日,用于监听
});

定义VM部分比较简单,有注释,且都是必填项。

初始化部分

avalon.ready(function(){
    date.init(dateVM);
});

实现逻辑部分

//- 日期联动效果使用说明
//- 使用时, 需要在VM中定义下面6个参数, 调用init方法, 把当前VM作为参数传进去就可以
//- 如果没有日的选项, day和dayArr可定义
//- 注意:使用时, 在View层的select必须使用ms-duplex进行双向绑定
//-     year : 1, 
//-     month : 1, 
//-     day : 1,(可不定义)
//-     yearArr : [],
//-     monthArr : [],
//-     dayArr : [](可不定义)
var date = {
    init : function(dateVM) {
        var _this = this;
        _this.initDate(dateVM);
        if(dateVM.day) {
            dateVM.$watch("year", function(){//- 监听年, 重新渲染日
                _this.renderDay(dateVM);
            });
            dateVM.$watch("month", function(){//- 监听月, 重新渲染日
                _this.renderDay(dateVM);
            });
        }
    },
    initDate : function(dateVM) {
        var _this = this;
        var yearArr = [];
        var monthArr = [];
        var dayArr = [];
        var today = new Date();
        var year = today.getFullYear();
        //- 填充yearArr, 只取当前年的前三年
        for(var i=year-dateVM.yearsAgo; i<=year; i++) {
            yearArr.push(i);
        }
        dateVM.year = year;//- 放到VM中
        dateVM.yearArr = yearArr;//- 放到VM中
        var month = today.getMonth()+1;
        //- 填充monthArr, 每年有十二个月
        for(var i=1; i<=12; i++) {
            monthArr.push(i);
        }
        dateVM.month = month;//- 放到VM中
        dateVM.monthArr = monthArr;//- 放到VM中
        if(dateVM.day) {//- 可能只需要年和月, 不需要日
            var day = today.getDate();
            //- 填充dayArr, 根据年和月的不同, 天数也不同
            var lastDay = _this.getLastDay(year, month);
            for(var i=1; i<=lastDay; i++) {
                dayArr.push(i);
            }
            dateVM.day = day;
            dateVM.dayArr = dayArr;
        }
    },
    renderDay : function(dateVM) {
        var _this = this;
        var lastDay = _this.getLastDay(dateVM.year, dateVM.month);
        if(dateVM.day > lastDay) {//- 解决当从5月切成2月时, 下拉为空的问题, 现在是定位到最后一天
            dateVM.day = lastDay;
        }
        var dayArr = [];
        for(var i=1; i<=lastDay; i++) {
            dayArr.push(i);
        }
        dateVM.dayArr = dayArr;
    },
    getLastDay : function(year,month){//- 获得某月的最后一天  
            var new_year = year;//- 取当前的年份          
            var new_month = month++;//- 取下一个月的第一天,方便计算(最后一天不固定)          
            if(month>12) {         
                new_month -=12;//- 月份减          
               new_year++;//- 年份增          
            }         
            var new_date = new Date(new_year,new_month,1);//- 取当年当月中的第一天          
            return (new Date(new_date.getTime()-1000*60*60*24)).getDate();//- 获取当月最后一天日期      
    }
}

 这里重点说下$watch部分,因为需要在切换年和月的时候要动态的计算这个月有多少天(就是二月),所以监控年和月,当他们改变的时候,会计算有多少天,并重新把dayArr里面的数据清空,重新填充,这样VM就会自动同步到V中,而不像jQuery一个,根据ID或者class,重新选择DOM,

拼HTML

原文地址:https://www.cnblogs.com/sunhk/p/5651376.html