如何处理Angular Material中md-datepicker与Moment.js的类型转换?
解决Angular Material md-datepicker与Moment.js类型转换问题
我完全懂你的痛点——md-datepicker硬要把绑定的Moment对象转成Date类型,搞得后续依赖Moment的代码直接报错。这里给你两个实用方案,帮你把模型始终维持在Moment类型:
方案一:自定义ngModel转换指令(推荐)
这种方式最符合Angular的双向绑定设计,而且可以复用在所有日期选择器上。我们通过ngModel的$formatters和$parsers管道,在视图和模型之间自动完成类型转换:
app.directive('momentDatepicker', function() { return { require: 'ngModel', link: function(scope, element, attrs, ngModel) { // 模型 -> 视图:把Moment转成Date给md-datepicker用 ngModel.$formatters.push(function(momentObj) { return momentObj ? momentObj.toDate() : null; }); // 视图 -> 模型:把md-datepicker返回的Date转回Moment ngModel.$parsers.push(function(dateObj) { return dateObj ? moment(dateObj) : null; }); } }; });
然后在你的日期选择器标签上加上这个指令就行:
<md-datepicker ng-model="momentfrom" md-open-on-focus="true" name="dateFrom" moment-datepicker> </md-datepicker>
这样不管用户怎么操作日期选择器,$scope.momentfrom都会一直保持Moment类型,完美适配你其他依赖Moment的函数。
方案二:监听模型变化自动转换(快速临时方案)
如果不想加额外指令,也可以在控制器里通过$watch监听变量,当它变成Date类型时自动转回Moment:
app.controller('YourController', function($scope) { // 初始化你的Moment变量 $scope.momentfrom = moment(); // 监听变量变化,自动转换类型 $scope.$watch('momentfrom', function(newVal) { if (newVal && newVal instanceof Date) { $scope.momentfrom = moment(newVal); } }, true); });
不过这个方案有个小缺点:$watch会带来额外的性能开销,而且只能在当前控制器生效,不如指令方案灵活。
另外你现有的$mdDateLocaleProvider配置是完全没问题的,它负责处理日期字符串和Date类型的转换,和上面的方案搭配起来就能实现完整的Moment与视图的无缝对接。
内容的提问来源于stack exchange,提问作者user3905270
相关产品推荐
相关产品推荐

