angularjs:解析日期输入

时间:2013-09-06 06:07:12

标签: date angularjs

我需要一个指令来解析用户输入到日期并验证它。所以我写了以下内容:

myDirectives.directive('myDate', function($filter) {
    'use strict';
    return {
        require:'ngModel',
        restrict:'A',
        link:function (scope, elem, attrs, ctrl) {
            var dateFormat = attrs.myDate ? attrs.myDate : 'shortDate';

            ctrl.$formatters.unshift(function(modelValue) {
                return $filter('date')(modelValue, dateFormat);
            });
            ctrl.$parsers.unshift(function(viewValue) {
                var date = new Date(viewValue);

                if (isNaN(date)) {
                    ctrl.$setValidity('date', false);
                    return undefined;
                } else {
                    var dateString = $filter('date')(date, dateFormat);
                    if (dateString !== viewValue) {
                        ctrl.$setViewValue(dateString);
                    }
                    ctrl.$setValidity('date', true);
                    return date;
                }
            });
        }
    };
});

只有在输入失去焦点后才需要进行解析,所以我使用另一个指令,我发现here。问题是

ctrl.$setViewValue(dateString);

不起作用,因为如angularjs文档中所示,必须从DOM事件处理程序中调用setViewValue()。我该怎么做才能反映出解析结果?

4 个答案:

答案 0 :(得分:2)

而不是

ctrl.$setViewValue(dateString);

我需要写

elem.val(dateString);

问题解决了。所以,我的指令现在如下所示:

myDirectives.directive('myDate', function ($filter) {
    'use strict';
    return {
        require: 'ngModel',
        restrict: 'A',
        link: function (scope, elem, attrs, ctrl) {
            var dateFormat = attrs.myDate ? attrs.myDate : 'shortDate';
            ctrl.$formatters.unshift(function (modelValue) {
                return (modelValue) ? $filter('date')(modelValue, dateFormat) : '';
            });
            ctrl.$parsers.unshift(function (viewValue) {
                var date = new Date(viewValue);
                if (isNaN(date)) {
                    ctrl.$setValidity('date', false);
                    return undefined;
                } else {
                    var dateString = $filter('date')(date, dateFormat);
                    if (dateString !== viewValue) {
                        elem.val(dateString);
                    }
                    ctrl.$setValidity('date', true);
                    return date;
                }
            });
            elem.unbind('input').unbind('keydown').unbind('change');
            elem.bind('blur', function () {
                scope.$apply(function () {
                    ctrl.$setViewValue(elem.val()); //this method name is misleading; 
                                                    //it actually sets model value?!
                });
            });
        }
    };
});

请注意,我在另一个指令中加入了代码,该指令负责在焦点丢失时将视图值推送到模型。

答案 1 :(得分:2)

我创建了一个将字符串转换为Date对象的日期解析器。您还可以提供正在使用的日期格式以及日期区域设置。它返回Date对象,有效或以其他方式取决于输入。

还有一个实现此解析器的指令,因此您可以在输入字段上使用它。例如。

https://github.com/dnasir/angular-dateParser

答案 2 :(得分:0)

这应该有效:

var setter = $parse('ngModel').assign;
setter($scope,valueToSet);
$scope.$apply() // This may be needed depending on where its done.

Refenece:http://docs.angularjs.org/api/ng.$parse

答案 3 :(得分:-1)

on html:

<input class="form-control""
type="date"
string-to-date
ng-model="val.VAL">

在Controller上创建一个指令

.directive('stringToDate', function() {
    return {
      require: 'ngModel',
      link: function(scope, element, attrs, ngModel) {
        ngModel.$parsers.push(function(value) {
          return new Date(value);
        });
        ngModel.$formatters.push(function(value) {
          var fechaactual = new Date(value);
          return fechaactual;
        });
      }
    };
  })

请注意,该指令调用stringToDate,您必须在html中将其称为字符串到日期。不要原因:))