如何强制日期输入绑定到模型作为JavaScript日期Date()

时间:2015-01-27 13:47:41

标签: angularjs angularjs-directive

我正在尝试从文本框中获取输入以将范围变量绑定为实际的JavaScript Date对象,而不是字符串。输入是动态生成的,因此在将值发送到服务器之前,我无法进行转换/转换。

到目前为止,我已经创建了一个指令,它使用moment.js来解析作用域上的值,并将其转换为Date()对象。问题似乎是角度将值立即转换回字符串。我想它会重新检查html输入并覆盖指令中设置的Date()对象。

Here is a working Plunkr demonstrating the issue

(function () {

    'use strict';

    angular.module('app', ['ng'])

    .controller('myController', ['$scope', function() {

        $scope.testObj = null;

    }]) 

    .directive('dateBinding', function () {

        return {

            restrict: 'A',
            require: 'ngModel',
            scope: false,
            link: function (scope, element, attrs, ngModel) {

                var parseFormat = attrs.dateBinding;

                scope.$watch(

                    function() { 

                      console.log('watching model', ngModel.$modelValue);

                      return ngModel.$modelValue;

                    }, 
                    function (val) {

              console.log('recieved model', val);

              if (val && typeof val == 'string') {

                console.log('attempting parse date', val);

                if(moment(val, parseFormat).isValid())
                {
                  console.log('string is valid date');

                  ngModel.$modelValue = moment(val, parseFormat).toDate();

                  console.log('completed value assignment', ngModel.$modelValue);

                  console.log('model is of type ' + typeof ngModel.$modelValue);

                  console.log('model is date', (ngModel.$modelValue instanceof Date));
                }
                else
                {
                  console.log('string is not a valid date');
                }
              }
                    }
                );
            }
        };
    })

} ());

您可以在运行plunkr时在浏览器中打开控制台来查看该行为。行'完成值赋值'表明至少暂时,ngModel。$ modelValue(来自$ scope.testObj)是一个Date()对象。

下面输出中的最后一行显示了手表再次触发,模型值再次成为html输入中显示的字符串。

enter image description here

如何将值保留为Date对象(一旦可以解析有效日期)。

1 个答案:

答案 0 :(得分:2)

您必须使用$parsers文档中描述的$formattersngModelController管道。代码是:

.directive('dateBinding', function () {

    return {

        restrict: 'A',
        require: 'ngModel',
        scope: false,
        link: function (scope, element, attrs, ngModel) {

            var parseFormat = attrs.dateBinding;

            function parse(value) {
              var m = moment(value, parseFormat);
              if( m && m.isValid() ) {
                  ngModel.$setValidity('dateBinding', true);
                return m.toDate();
              }
              else {
                  ngModel.$setValidity('dateBinding', false);
                return; // undefined
              }
            }

            function format(value) {
              if( value && value instanceof Date ) {
                return moment(d).format(parseFormat);
              }
              else {
                return '';
              }
            }

            ngModel.$formatters.push(format);
            ngModel.$parsers.unshift(parse);
        }
    };
});

查看(和玩)分叉的插件:http://plnkr.co/edit/VboH2iq6HRlaDhX3g1AY?p=preview