Angular指令封裝jQuery日期時間插件datetimepicker實現雙向綁定

jopen 8年前發布 | 185K 次閱讀 jQuery Web框架 angularjs

一放假就高產似母豬了。

00.混亂的前端界

Angular1.x確實是個學習成本很高的框架,剛開始實習那會兒,前端啥也不懂,工頭說用Angular,我們這群小弟也只能硬著頭皮學。在這之前,前端的東西大部分都用的jQuery,而Angular正好是和jQuery的思維是相反的,開發過程中遇到了不少坑。而Angular團隊也放棄了1.x開始開發和React神似的2.0版本,唉,真是滄海桑田啊。

01.Angular vs jQuery

Angular模塊化和解耦的思路確實值得一學,但是相對于成熟的jQuery插件庫,Angular就顯得寒酸了不少,比如,Angular-UI中日期控件是這樣的:

丑的不要不要的,還不能選時間,相比之下jQuery就有很多優秀的控件了比如這樣的:

此插件傳送門: http://xdsoft.net/jqplugins/datetimepicker/

那么問題來了,控件一般是直接像這樣$("#xx").val("xx")直接塞值進<input />標簽的,這 不會觸發ng-change事件 ,ng-model也不會被更新 ,于是筆者寫了個Angular適配指令,來實現這個控件的雙向綁定,對于其他jQuery插件,也可以用類似的思路來進行適配。

10.干貨

下面是一個Demo,比較兩者的不同,注意右邊ng-bind的屬性使用adapter是會 同步變化 的↓

Demo傳送門: http://ydxxwb.sinaapp.com/angularTimePicker/

Github地址: https://github.com/Code2Life/angular.DatetimePicker.git

 angular.module("directives",[]).directive("datetimepicker",function(){
    return {
        restrict: "EA",   //指令作用范圍是element或attribute
        require : "ngModel",  //控制器是指令標簽對應的ngModel
        link: function (scope, element, attrs, ctrl) {

            var unregister = scope.$watch(function(){               //關鍵點,下面詳述

                $(element).append("<input id='date-"+attrs.dateid+"' style='border:none;width:100%' value='"+ctrl.$modelValue+"'>"); //template用不好,于是用這個笨辦法加上input標簽

                element.on('change', function() {  //注冊onChange事件,設置viewValue
                    scope.$apply(function() {
                        ctrl.$setViewValue($("#date-"+attrs.dateid).val());
                    });
                });

                element.on('click',function(){    //click觸發日期框
                    $("#date-"+attrs.dateid).datetimepicker({ 
                        format : attrs.format || 'Y/m/d h:i',   //格式
                        onClose : function(){                   //關閉日期框時手動觸發change事件
                            element.change();
                        }
                    });
                });

                element.click();        //第一次綁定事件,模擬一次click,否則肯能要點兩下才會出日期框

                return ctrl.$modelValue;
            }, initialize);

            function initialize(value){  //下面再說
                ctrl.$setViewValue(value);
                unregister();
            }
        }
    }
});

寫這個指令過程中遇到了一個大坑,查了很久才明白,Angular初始化一個ngModel的時候,是會 先給它的value置為NaN ,初始化必須要先調用$watch()來監測真正值被設置的時候,然后調用上面的initialize方法來設置view值。 否則在Controller中設置的初始值會變成NaN。

11.不足之處

原插件是有很多可選項的,我只實現了一個最基本的format,有其他需求的自行改代碼吧。可以利用第三個attrs參數獲取屬性,然后調用原插件的配置方法,來實現更復雜的邏輯。

來自: http://www.cnblogs.com/code2life/p/5097330.html

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!