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

一放假就高產似母豬了。前端

00.混亂的前端界

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

01.Angular vs jQuery

Angular模塊化和解耦的思路確實值得一學,可是相對於成熟的jQuery插件庫,Angular就顯得寒酸了很多,好比,Angular-UI中日期控件是這樣的:github

醜的不要不要的,還不能選時間,相比之下jQuery就有不少優秀的控件了好比這樣的:app

此插件傳送門: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/ui

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


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。.net

11.不足之處

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

相關文章
相關標籤/搜索