博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用avalon MVVM框架打造jquery ui的日历
阅读量:5940 次
发布时间:2019-06-19

本文共 9382 字,大约阅读时间需要 31 分钟。

我直接把jquery datepicker的结构抄过来,类名也照搬。于是一个换肤的日历就诞生了。

Prev
Next
{
{title}}
{ {date}}
{ {day.split('-')[2]}}
可选择月份
可选择年份
显示按钮面板
显示其他月份的日期
你喜欢的皮肤

你选择的日期为 {

{selectedDate | date('yyyy-MM-dd')}}

上面的结构分两部分,最上的日历,下面的一些表单元素用于控制日历的配置。

avalon.ready(function() {               avalon.define("datepicker", function(vm) {                    //配置                    vm.changeYear = false                    vm.changeMonth = false                    vm.minDate = new Date(2013, 3, 25);                    //vm.maxDate                    vm.showOtherMonths = false;                    vm.showButtonPanel = false;                    //当前时间                    vm.selectedDate = new Date;                    vm.currentDate = new Date;                    vm.currentMonth = vm.currentDate.getMonth();                    vm.currentYear = vm.currentDate.getFullYear();                    vm.currentWeeks = getWeeks(vm.currentDate);                    //显示顶部的年份与月份                    vm.title = {                        get: function() {                            var format = "";                            if (!this.changeYear && this.changeMonth) {                                format = "yyyy年";                            } else if (this.changeYear && !this.changeMonth) {                                format = "MMMM";                            } else if (!this.changeYear && !this.changeMonth) {                                format = "MMMM yyyy年";                            }                            return format && avalon.filters.date(this.currentDate, format);                        }                    };                    //星期显示                    vm.$weeks = "日一二三四五六".split("");                    //月份下拉菜单                    vm.$months = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]                    //当月的日期                    function isDisabled(time) {                        var disabled = false;                        if (vm.minDate) {                            disabled = time < vm.minDate;                        }                        if (disabled && vm.maxDate) {                            disabled = time > vm.maxDate;                        }                        return disabled - 0;                    }                    function  getWeeks(cur) {                        vm.currentDate = cur;                        var year = cur.getFullYear();                        var month = cur.getMonth();//得到今天是几月(0 ~ 11)                        var date = cur.getDate();  //得到今天是几号 (1 ~ 31)                        cur.setMonth(month + 1);//改为下一个月,                        //由于日期是1 ~ 31, 0则是退到上一个月的最后一天,于是得到这个月的总天数                        cur.setDate(0);                        var num = cur.getDate();                        var next = 6 - cur.getDay();                        var dates = avalon.range(1, num + 1);                        dates = dates.map(function(d) {                            var time = new Date(year, month, d)                            return [year, month, d, isDisabled(time)].join("-");                        });                        cur.setMonth(month);                        cur.setDate(1);//得到当月的第一天                        var prev = cur.getDay();//0 ~ 6                        cur.setDate(date);//还原                        for (var i = 0; i < prev; i++) {//补上上一个月的日期                            cur = new Date(year, month, -1 * i)                            dates.unshift([year, cur.getMonth(), cur.getDate(), isDisabled(cur)].join("-"))                        }                        for (var i = 0; i < next; i++) {//补上下一个月的日期                            cur = new Date(year, month + 1, i + 1)                            dates.push([year, cur.getMonth(), cur.getDate(), isDisabled(cur)].join("-"))                        }                        var ret = [];                        while (dates.length) {//每行七个分组                            ret.push(dates.splice(0, 7));                        }                        return ret;//一个三维数组                    }                    //取得当年的前后20年                    function getYears() {                        var y = vm.currentYear;                        return avalon.range(y - 10, y + 10);                    }                    vm.candidateYears = getYears();                    //点击事件                    vm.theme = "start";                    vm.nextMonth = function(e) {                        e.preventDefault()                        var d = vm.currentDate;                        var m = d.getMonth();                        d.setMonth(m + 1);                        m = d.getMonth();                        if (m === 0) {                            var y = d.getFullYear();                            vm.currentYear = y;                        }                        vm.currentMonth = m;                    };                    //点击事件                    vm.prevMonth = function(e) {                        e.preventDefault()                        var d = vm.currentDate;                        var m = d.getMonth();                        d.setMonth(m - 1);                        m = d.getMonth();                        if (m === 11) {                            var y = d.getFullYear();                            vm.currentYear = y;                        }                        vm.currentMonth = m;                    };                    //侦听                    vm.$watch("currentMonth", function(val) {                        var d = vm.currentDate;                        d.setMonth(val);                        vm.currentWeeks = getWeeks(d);                        vm.title = NaN;                    });                    vm.$watch("currentYear", function(val) {                        var d = vm.currentDate;                        d.setFullYear(val)                        vm.currentWeeks = getWeeks(d);                        vm.title = NaN;                    });                    //高亮当前选中的日期                    vm.selectDay = function(e) {                        var el = e.target;                        e.preventDefault()                        if (el.tagName === "A" && el.parentNode.tagName === "TD" && !/disabled/.test(el.className)) {                            var d = el.$scope.day.split('-')                            vm.selectedDate = new Date(d[0], d[1], d[2]);                        }                    };                    //高亮今天的日期                    var today = new Date;                    var atoday = [today.getFullYear(), today.getMonth(), today.getDate()];                    vm.isToday = function() {                        var day = this.$scope.day;                        return day.slice(0, day.lastIndexOf("-")) === atoday.join("-");                    };                    vm.backToday = function() {                        vm.currentMonth = atoday[1];                        vm.currentYear = atoday[0];                    }                });                avalon.scan();            });

这个JS代码比起先前的更清晰,放弃使用$fire这个危险的操作,建议大家也不要用它。因为如果没有严格的值变动检测, 这很容易引起无限递归。 现在avalon已经完全重用现有的节点,不会像过去那样每次都清空然后又添加。因此性能更好。

{
{month+1}}月{
{year}}年 {
{title}}
{
{date}}
Today Done
可选择月份
可选择年份
显示按钮面板
显示其他月份的日期
startsmoothnessflicksunnyexcite bikeblack tietrontasticswanky pursele frogblitzerdot luvmint-chochot sneaks south streethumanityvadereggplantcupertinoovercast选择你喜欢的皮肤(注:这些样式都受到博客园染指了)

你选择的日期为 {

{selectedDate | date('yyyy-MM-dd')}}

所有JS代码不到150行,就能涵盖jquery ui datepicker(2000多行)的绝大多数功能。如果努力一点,把模板也封装一下,其他功能也跟进,最多也是500行的规模。可谓的威力。而且这样写JS,可读性非常好,思路不会像着jQuery那样跟着CSS表达式——“这个元素是在哪里,该添加类名还是移除类名……”

用了后,我们写代码的思路将是这个样子

  1. 先把HTML搞出来;
  2. 把重复的部分转换为一个each绑定,VM中对应一个数组;
  3. 把页面视情况要显示隐藏,要切换类名的东西,在VM中由一个布尔属性来控制;
  4. 事件回调里再来也不进行DOM操作,而是对这些数组进行shift, pop操作,布尔属性进行反转;
  5. 把这些逻辑封到一个VM中
  6. 最后对视图进行绑定

转载地址:http://hkmtx.baihongyu.com/

你可能感兴趣的文章
基于托管C++的增删改查及异步回调小程序
查看>>
Oracle DBMS_STATS 包 和 Analyze 命令的区别
查看>>
给Visual Studio 2010中文版添加Windows Phone 7模板
查看>>
linux下基本命令
查看>>
windows server 2008R2 上安装配置freesshd
查看>>
手动删除SVCH0ST.EXE的方法
查看>>
已释放的栈内存
查看>>
Android网络之数据解析----SAX方式解析XML数据
查看>>
Java递归列出所有文件和文件夹
查看>>
[关于SQL]查询成绩都大于80分的学生
查看>>
Delphi(Tuxedo,BDE,ADO)三合一数据集组件HsTxQuery
查看>>
java之ibatis数据缓存
查看>>
“TNS-03505:无法解析名称”问题解决一例
查看>>
LeetCode - Longest Common Prefix
查看>>
Android图片处理
查看>>
2015年第21本:万万没想到,用理工科思维理解世界
查看>>
大家谈谈公司里的项目经理角色及职责都是干什么的?
查看>>
剑指offer
查看>>
Velocity魔法堂系列二:VTL语法详解
查看>>
NopCommerce架构分析之八------多语言
查看>>