zoukankan      html  css  js  c++  java
  • 使用avalon MVVM框架编写日历控件

    本教程将介绍avalon的高级特性

    • date过滤器的使用, 这个与angular的date过滤器的使用方法差不多,{{xxx|date("yyyy MM d")}}
    • $watch监听,相当于把监控属性变成一种事件,当它变化时,就执行它绑定的回调。vm.$watch("firstName", function(){alert("我是回调")})
    • 不监听属性或方法的定义,就是$开头,或放在$skipArray数组中。
    • if绑定,类似于knockout的if绑定,根据求值表达式的情况决定把当前元素插入DOM树。ms-if=expr

    HTML结构

    <div ms-controller="datepicker">
            <div class="ui-datepicker">
                <div class="ui-datepicker-header">
                    <a href="###" title="Prev" class="ui-datepicker-month ui-datepicker-prev" ms-click="prevMonth">
                        <
                    </a>
                    <a href="###"title="Next" class="ui-datepicker-month ui-datepicker-next" ms-click="nextMonth">
                        >
                    </a >
                    <div class="ui-datepicker-title" >
                        <select ms-each-month="$months" ms-if="changeMonth" ms-model="currentMonth" >
                            <option value="{{month}}" ms-selected="currentMonth === month">{{month+1}}月</option>
                        </select>
                        <select ms-each-year="candidateYears" ms-if="changeYear" ms-model="currentYear" >
                            <option value="{{year}}" ms-selected="currentYear === year">{{year}}年</option>
                        </select>
                        {{title}}
                    </div>
    
                </div>
                <table ms-click="select">
                    <thead>
                        <tr ms-each-date="$weeks">
                            <th>{{date}}</th>
                        </tr>
                    </thead>
                    <tbody ms-each-week="candidateWeeks">
                        <tr ms-each-day="week" >
                            <td><span ms-visible="day" ms-class-selected="isSelected" ms-class-disabled="day && day[3]" ms-class-today="isToday" >{{ day[2] }}</span></td>
                        </tr>
                    </tbody>
                </table>
    
            </div>
            <p><input type="radio" ms-model="changeMonth" />可选择月份</br/>
                <input type="radio" ms-model="changeYear" />可选择年份</p>
            <div class="font">{{selectedDate | date("yyyy-MM-d")}}</div>
      </div>
                    

    JS

                  avalon.ready(function() {
                    var model = avalon.define("datepicker", function(vm) {
    	           //配置
                        vm.changeYear = false
                        vm.changeMonth = false
                        vm.minDate = new Date(2013, 4, 25)
                        
                        //当前时间
                        vm.current = new Date;
                        vm.currentMonth = vm.current.getMonth();
                        vm.currentYear = vm.current.getFullYear();
                        vm.selectedDate = new Date;
                        //显示顶部的年份与月份
                        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.current, format);
                            }
                        };
    					//星期显示
                        vm.$weeks = "日一二三四五六".split("");
    					//月份下拉菜单
                        vm.$months = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
                        //当月的日期
                        function  getWeeks() {
                            var cur = vm.current;
                            var year = cur.getFullYear();
                            var month = cur.getMonth();
                            var date = cur.getDate()
                            cur.setMonth(month + 1);
                            cur.setDate(0);
                            var num = cur.getDate();
                            var dates = avalon.range(1, num + 1);
                            dates = dates.map(function(d) {
                                var timestamp = new Date(year, month + 1, d) - 0
                                var disabled = false;
                                if (vm.minDate) {
                                    disabled = timestamp < vm.minDate - 0;
                                }
                                if (disabled && vm.maxDate) {
                                    disabled = timestamp > vm.maxDate - 0;
                                }
                                return [ year, month, d, disabled];
                            });
                            cur.setMonth(month);
                            cur.setDate(1);
                            var before = cur.getDay();
                            var shim = new Array(before);//如果当月的第一天不是星期天,需要补空格
                            dates = shim.concat(dates);
                            cur.setDate(date);//还原
                            var ret = [];
                            while (dates.length) {//每行七个分组
                                ret.push(dates.splice(0, 7));
                            }
                            return ret;
                        }
                        vm.candidateWeeks = getWeeks();
                        //取得当年的前后20年
                        function getYears() {
                            var y = vm.currentYear;
                            return avalon.range(y - 10, y + 10);
                        }
                        vm.candidateYears = getYears();
                        //点击事件
                        vm.nextMonth = function() {
                            var date = vm.current;
                            var m = date.getMonth();
                            vm.$fire("currentMonth", m + 1)
                        };
    					//点击事件
                        vm.prevMonth = function() {
                            var date = vm.current;
                            var m = date.getMonth();
                            vm.$fire("currentMonth", m - 1);
                        };
    					//侦听
                        vm.$watch("currentMonth", function(month) {
                            var date = vm.current;
                            date.setMonth(month);
    			vm.currentMonth = month;
                            vm.candidateWeeks = getWeeks();
                            vm.title = date - 0;
                        });
                        vm.$watch("currentYear", function(year) {
                            var date = vm.current;
                            date.setFullYear(year);
    			vm.currentYear = year;
                            vm.$fire("currentMonth", date.getMonth());
                        });
    
    
                        //高亮当前选中的日期
                        vm.select = function(e) {
                            var el = e.target;
                            if (el.tagName === "SPAN" && el.parentNode.tagName === "TD" && !/disabled/.test(el.className)) {
                                vm.selected = el.innerHTML;
                                var d = el.$scope.day.slice(0, 3);
                                vm.selectedDate = new Date(d[0],d[1],d[2]);
                            }
                        };
                        vm.selected = "";
                        vm.isSelected = function() {
                            return  this.innerHTML === vm.selected;
                        };
                        //高亮今天的日期
                        var today = new Date;
                        today = [ today.getFullYear(), today.getMonth(), today.getDate() ].join();
                        vm.isToday = function() {
                            var day = this.$scope && this.$scope.day;
                            return day && day.slice(0, 3).join() === today;
                        };
                    });
                    avalon.scan();
                });
    
                    
    日历
    < >
    {{title}}
    {{date}}
    {{ day[2] }}
    可选择月份
    可选择年份

    {{selectedDate | date("yyyy-MM-d")}}

    这就完成了,如果要用jQuery实现相似的功能,起码要千行。主要原因是MVVM的核心是数据。数据是底层、是心脏,数据变了,作为表层的UI就会跟着变,将数据展现给用户;如果用户修改了UI元素上的值,相当于透过UI元素直接修改了底层的数据;数据处于核心地位,UI处于从属地位。DOM操作全部隐藏在UI的绑定中(ms-html,就是调用innerHTML操作,ms-on-click进行事件绑定, ms-class-*,就是调用增删类名,ms-visible控制了元素的显隐,ms-if,ms-each进行流程控制处理某个区域的所有元素的生成移除……),由框架自动维护,我们只需要关注业务逻辑!

    机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
  • 相关阅读:
    PE系统盘
    python常用方法手记
    python tushare
    idea导入导出java jar包
    javaweb项目配置tomcat启动
    window安装tomcat
    解决idea控制台乱码
    maven手记
    java redis常见问题
    java mysql常见问题
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/3050564.html
Copyright © 2011-2022 走看看