使用avalon MVVM架構編寫日曆控制項

來源:互聯網
上載者:User
文章目錄
  • HTML結構
  • JS

本教程將介紹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();            });                

日曆


>

{{month+1}}月{{year}}年

{{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進行流程式控制制處理某個地區的所有元素的產生移除……),由架構自動維護,我們只需要關注商務邏輯!


posted on 2013-04-29 13:20 司徒正美 閱讀(...) 評論(...) 編輯 收藏

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.