4

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

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;
                }
            });
        }
    };
});

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

ctrl.$setViewValue(dateString);

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

4

4 回答 4

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?!
                });
            });
        }
    };
});

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

于 2013-09-09T05:57:47.443 回答
2

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

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

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

于 2014-02-19T21:48:09.613 回答
0

这应该有效:

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

参考: http ://docs.angularjs.org/api/ng.$parse

于 2013-09-06T12:18:50.910 回答
-1

在 html 上:

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

在控制器上创建一个指令

.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 中将其称为 string-to-date。不要不为什么:)

于 2016-03-20T01:16:34.120 回答