一放假就高产似母猪了。前端
Angular1.x确实是个学习成本很高的框架,刚开始实习那会儿,前端啥也不懂,工头说用Angular,咱们这群小弟也只能硬着头皮学。在这以前,前端的东西大部分都用的jQuery,而Angular正好是和jQuery的思惟是相反的,开发过程当中遇到了很多坑。而Angular团队也放弃了1.x开始开发和React神似的2.0版本,唉,真是沧海桑田啊。git
Angular模块化和解耦的思路确实值得一学,可是相对于成熟的jQuery插件库,Angular就显得寒酸了很多,好比,Angular-UI中日期控件是这样的:github
丑的不要不要的,还不能选时间,相比之下jQuery就有不少优秀的控件了好比这样的:app
此插件传送门:http://xdsoft.net/jqplugins/datetimepicker/框架
那么问题来了,控件通常是直接像这样$("#xx").val("xx")直接塞值进<input />标签的,这不会触发ng-change事件,ng-model也不会被更新,因而笔者写了个Angular适配指令,来实现这个控件的双向绑定,对于其余jQuery插件,也能够用相似的思路来进行适配。模块化
下面是一个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
原插件是有不少可选项的,我只实现了一个最基本的format,有其余需求的自行改代码吧。能够利用第三个attrs参数获取属性,而后调用原插件的配置方法,来实现更复杂的逻辑。