admin管理员组

文章数量:1323157

Hope anyone else also observed this:-

We are using AngularJS 1.0 and using type="date" with element to get Chrome's nice default datetime picker. Everything was working fine till chrome updated itself recently to [24.0.1312.52]. Now If I change date using datetime picker, AngularJS data binding does not save it to bind json property of $scope.

If I change date via any keyboard key down, Data binding saves the date to property bind.

What could be the reason causing this problem.?

Hope anyone else also observed this:-

We are using AngularJS 1.0 and using type="date" with element to get Chrome's nice default datetime picker. Everything was working fine till chrome updated itself recently to [24.0.1312.52]. Now If I change date using datetime picker, AngularJS data binding does not save it to bind json property of $scope.

If I change date via any keyboard key down, Data binding saves the date to property bind.

What could be the reason causing this problem.?

Share asked Jan 17, 2013 at 10:57 AnandAnand 4,55110 gold badges49 silver badges74 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

I have noticed the same behavior and noticed that Sutikshan was on the right path.

HTML 5 input date requires the value to be in RF 3339 format, therefore, we can adjust our AngularJS input directive to format and parse the value accordingly.

angular.module('myApp', []).directive('input', ['$filter',
function($filter) {
    return {
        require: '?ngModel',
        restrict: 'E',
        link: function(scope, element, attrs, ngModel) {
            if (!ngModel || attrs.type != "date") return;

            // Using AngularJS built in date filter, convert our date to RFC 3339
            ngModel.$formatters = [function(value) {
                return value && angular.isDate(value)
                    ? $filter('date')(value, 'yyyy-MM-dd')
                    : '';
            }];

            // Convert the string value to Date object.
            ngModel.$parsers = [function(value) {
                return value && angular.isString(value)
                    ? new Date(value)
                    : null;
            }];
        }
    };
}]);

The basics is that we ensure that the NgModelController uses our $formatters and $parsers when updating the view value and model value, respectively.

We got help in angularJS google group:-

https://groups.google./forum/?fromgroups=#!topic/angular/ycYzD3xRKS8

JSFeedle by Peter Bacon Darwin

http://jsfiddle/ZsRxj/

var module = angular.module('demoApp',[]);

module.directive('input', function () {
  return {
    require: '?ngModel',
    restrict: 'E',
    link: function (scope, element, attrs, ngModel) {
      if ( attrs.type="date" && ngModel ) {
        element.bind('change', function () {
          scope.$apply(function() {
            ngModel.$setViewValue(element.val());
          });
        });
      }
    }
  };
});

It seems that Chrome doesn't fire input when you select a date via the picker. A short-term hack is to forward change events (which Chrome does fire) to input; fortunately AngularJS doesn't use the event itself in the listener, so you don't need to worry about mapping event values or anything:

$('body').on('change', 'input[type="date"]', null, function(){
  $(this).trigger('input');
});

A better solution would be to figure out why Chrome isn't firing input.

Caveat: while there doesn't seem to be anywhere in the AngularJS code that would cause change to fire (thereby starting an infinite loop), and cursory testing implied the above works, the "better solution" would be a much better solution.

本文标签: