Angular Формат даты даты в формате bootstrap не форматирует значение ng-model

Я использую bootstrap date-picker в моем приложении angular. Однако, когда я выбираю дату из этой модели выбора даты, лежащей в основе ng-модели, которую я обновляю, мне нужна эта ng-модель в одном формате даты "MM/dd/yyyy". но он каждый раз делает такую ​​дату

"2009-02-03T18:30:00.000Z"

вместо

02/04/2009

Я создал plunkr для той же ссылки plunkr

Мой код Html и контроллера выглядит ниже

<!doctype html>
<html ng-app="plunker">
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.js"></script>
    <script src="example.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>

<div ng-controller="DatepickerDemoCtrl">
    <pre>Selected date is: <em>{{dt | date:'MM/dd/yyyy' }}</em></pre>
    <p>above filter will just update above UI but I want to update actual ng-modle</p>


    <h4>Popup</h4>
    <div class="row">
        <div class="col-md-6">
            <p class="input-group">
              <input type="text" class="form-control"
              datepicker-popup="{{format}}" 
              ng-model="dt"
              is-open="opened" min-date="minDate"
              max-date="'2015-06-22'" 
              datepicker-options="dateOptions" 
              date-disabled="disabled(date, mode)" 
              ng-required="true" close-text="Close" />
              <span class="input-group-btn"> 
                <button type="button" class="btn btn-default" ng-click="open($event)">
                <i class="glyphicon glyphicon-calendar"></i></button>
              </span>
            </p>
        </div>
    </div>
    <!--<div class="row">
        <div class="col-md-6">
            <label>Format:</label> <select class="form-control" ng-model="format" ng-options="f for f in formats"><option></option></select>
        </div>
    </div>-->

    <hr />
    {{dt}}
</div>
  </body>
</html>

Angular контроллер

angular.module('plunker', ['ui.bootstrap']);
var DatepickerDemoCtrl = function ($scope) {


  $scope.open = function($event) {
    $event.preventDefault();
    $event.stopPropagation();

    $scope.opened = true;
  };

  $scope.dateOptions = {
    formatYear: 'yy',
    startingDay: 1
  };


  $scope.format = 'dd-MMMM-yyyy';
};

Заранее благодарим за рассмотрение моего вопроса.

UPDATE

Я вызываю ниже метод отправки моих данных, а VAR - массив размером 900, который содержит переменные выбора даты.

public SaveCurrentData(formToSave: tsmodels.ResponseTransferCalculationModelTS) {

        var query = this.EntityQuery.from('SaveFormData').withParameters({
            $method: 'POST',
            $encoding: 'JSON',
            $data: {
                VAR: formToSave.VAR,
                X: formToSave.X,
                CurrentForm: formToSave.currentForm,
            }
        });

        var deferred = this.q.defer();

        this.manager.executeQuery(query).then((response) => {
            deferred.resolve(response);
        }, (error) => {
                deferred.reject(error);
            });

        return deferred.promise;
    }

Ответ 1

Хотя подобные ответы были опубликованы, я хотел бы внести вклад в то, что казалось самым простым и самым чистым решением для меня. Предполагая, что вы используете дампинг AngularUI, и ваше начальное значение для ng-Model не форматируется, просто добавив следующую директиву в ваш проект, исправите проблему:

angular.module('yourAppName')
.directive('datepickerPopup', function (){
    return {
        restrict: 'EAC',
        require: 'ngModel',
        link: function(scope, element, attr, controller) {
      //remove the default formatter from the input directive to prevent conflict
      controller.$formatters.shift();
  }
}
});

Я нашел это решение в проблемах Github AngularUI, и поэтому все кредиты предоставляются людям там.

Ответ 2

Вы можете использовать $parsers, как показано ниже, это разрешило это для меня.

window.module.directive('myDate', function(dateFilter) {
  return {
    restrict: 'EAC',
    require: '?ngModel',
    link: function(scope, element, attrs, ngModel) {
      ngModel.$parsers.push(function(viewValue) {
        return dateFilter(viewValue,'yyyy-MM-dd');
      });
    }
  };
});

HTML:

<p class="input-group datepicker" >
  <input
     type="text"
     class="form-control"
     name="name"
     datepicker-popup="yyyy-MM-dd"
     date-type="string"
     show-weeks="false"
     ng-model="data[$parent.editable.name]" 
     is-open="$parent.opened"
     min-date="minDate"
     close-text="Close"
     ng-required="{{editable.mandatory}}"
     show-button-bar="false"
     close-on-date-selection="false"
     my-date />
  <span class="input-group-btn">
    <button type="button" class="btn btn-default" ng-click="openDatePicker($event)">
      <i class="glyphicon glyphicon-calendar"></i>
    </button>
  </span>
</p>

Ответ 3

Я столкнулся с той же проблемой, и через пару часов регистрации и расследования я исправил ее.

Оказалось, что в первый раз значение задается в сборщике даты, $viewValue - это строка, поэтому dateFilter отображает ее как есть. Все, что я сделал, это разбить его на объект Date.

Искать этот блок в файле ui-bootstrap-tpls

  ngModel.$render = function() {
    var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : '';
    element.val(date);

    updateCalendar();
  };

и замените его на:

  ngModel.$render = function() {
    ngModel.$viewValue = new Date(ngModel.$viewValue);
    var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : '';
    element.val(date);

    updateCalendar();
  };

Надеюсь, это поможет:)

Ответ 4

format format - это формат отображаемой даты. Основной ngModel - объект Date. При попытке отобразить его будет отображаться его по умолчанию, стандартное представление.

Вы можете показать его, как хотите, с помощью фильтра date в представлении или, если вам нужно его разобрать в контроллере, вы можете ввести $filter в свой контроллер и называть его $filter('date')(date, format), См. Также документы фильтра даты.

Ответ 5

Вы можете использовать formatters после выбора значения внутри вашей директивы datepicker. Например

angular.module('foo').directive('bar', function() {
    return {
        require: '?ngModel',
        link: function(scope, elem, attrs, ctrl) {
            if (!ctrl) return;

            ctrl.$formatters.push(function(value) {
                if (value) {
                    // format and return date here
                }

                return undefined;
            });
        }
    };
});

LINK.

Ответ 6

С таким количеством уже написанных ответов, вот мой прием.

С Angular 1.5.6 и ui-bootstrap 1.3.3 просто добавьте это в модель, и все готово.

ng-model-options="{timezone: 'UTC'}" 

Примечание. Используйте это только в том случае, если вас беспокоит дата на 1 день и не беспокоит дополнительное время T00: 00: 00.000Z

Обновлен Plunkr Здесь:

http://plnkr.co/edit/nncmB5EHEUkZJXRwz5QI?p=preview

Ответ 7

Все предлагаемые решения не сработали для меня, но самый близкий из них - от @Rishii.

Я использую AngularJS 1.4.4 и UI Bootstrap 0.13.3.

.directive('jsr310Compatible', ['dateFilter', 'dateParser', function(dateFilter, dateParser) {
  return {
    restrict: 'EAC',
    require: 'ngModel',
    priority: 1,
    link: function(scope, element, attrs, ngModel) {
      var dateFormat = 'yyyy-MM-dd';

      ngModel.$parsers.push(function(viewValue) {
        return dateFilter(viewValue, dateFormat);
      });

      ngModel.$validators.date = function (modelValue, viewValue) {
        var value = modelValue || viewValue;

        if (!attrs.ngRequired && !value) {
          return true;
        }

        if (angular.isNumber(value)) {
          value = new Date(value);
        }

        if (!value) {
          return true;
        }
        else if (angular.isDate(value) && !isNaN(value)) {
          return true;
        }
        else if (angular.isString(value)) {
          var date = dateParser.parse(value, dateFormat);
          return !isNaN(date);
        }
        else {
          return false;
        }
      };
    }
  };
}])

Ответ 8

Я могу исправить это, добавив ниже код в свой JSP файл. Теперь оба значения модели и UI одинаковы.

<div ng-show="false">
    {{dt = (dt | date:'dd-MMMM-yyyy') }}
</div>  

Ответ 9

Шаги по изменению формата даты по умолчанию для ng-model

Для разных форматов даты проверьте значения формата даты jqeryui datepicker здесь, например, я использовал dd/mm/yy

Создать директиву angularjs

angular.module('app', ['ui.bootstrap']).directive('dt', function () {
return {
    restrict: 'EAC',
    require: 'ngModel',
    link: function (scope, element, attr, ngModel) {
        ngModel.$parsers.push(function (viewValue) {
           return dateFilter(viewValue, 'dd/mm/yy');
        });
    }
 }
});

Запись dateFilter function

function dateFilter(val,format) {
    return $.datepicker.formatDate(format,val);
}

В html-странице напишите ng-модальный атрибут

<input type="text" class="form-control" date-type="string"  uib-datepicker-popup="{{format}}" ng-model="src.pTO_DATE" is-open="popup2.opened" datepicker-options="dateOptions" ng-required="true" close-text="Close" show-button-bar="false" show-weeks="false" dt />

Ответ 10

Наконец, я получил отличное решение этой проблемы. angular -strap имеет точно такую ​​же функцию, которую я ожидаю. Просто применяя date-format="MM/dd/yyyy" date-type="string", я получил ожидаемое поведение обновления ng-модели в данном формате.

<div class="bs-example" style="padding-bottom: 24px;" append-source>
    <form name="datepickerForm" class="form-inline" role="form">
      <!-- Basic example -->
      <div class="form-group" ng-class="{'has-error': datepickerForm.date.$invalid}">
        <label class="control-label"><i class="fa fa-calendar"></i> Date <small>(as date)</small></label>
        <input type="text"  autoclose="true"  class="form-control" ng-model="selectedDate" name="date" date-format="MM/dd/yyyy" date-type="string" bs-datepicker>
      </div>
      <hr>
      {{selectedDate}}
     </form>
</div>

здесь работает plunk ссылка

Ответ 11

Определение новой директивы для обхода ошибки не является идеальным.

Поскольку datepicker отображает более поздние даты правильно, одним простым обходным решением может быть просто установка переменной модели в null сначала, а затем на текущую дату через некоторое время:

$scope.dt = null;
$timeout( function(){
    $scope.dt = new Date();
},100);

Ответ 12

Директива datepicker (и datepicker-popup) требует, чтобы ng-модель была объектом Date. Это описано здесь.

Если вы хотите, чтобы ng-модель была строкой в ​​определенном формате, вы должны создать директиву обертки. Вот пример (Plunker):

(function () {
    'use strict';

    angular
        .module('myExample', ['ngAnimate', 'ngSanitize', 'ui.bootstrap'])
        .controller('MyController', MyController)
        .directive('myDatepicker', myDatepickerDirective);

    MyController.$inject = ['$scope'];

    function MyController ($scope) {
      $scope.dateFormat = 'dd MMMM yyyy';
      $scope.myDate = '30 Jun 2017';
    }

    myDatepickerDirective.$inject = ['uibDateParser', '$filter'];

    function myDatepickerDirective (uibDateParser, $filter) {
        return {
            restrict: 'E',
            scope: {
                name: '@',
                dateFormat: '@',
                ngModel: '='
            },
            required: 'ngModel',
            link: function (scope) {

                var isString = angular.isString(scope.ngModel) && scope.dateFormat;

                if (isString) {
                    scope.internalModel = uibDateParser.parse(scope.ngModel, scope.dateFormat);
                } else {
                    scope.internalModel = scope.ngModel;
                }

                scope.open = function (event) {
                    event.preventDefault();
                    event.stopPropagation();
                    scope.isOpen = true;
                };

                scope.change = function () {
                    if (isString) {
                        scope.ngModel = $filter('date')(scope.internalModel, scope.dateFormat);
                    } else {
                        scope.ngModel = scope.internalModel;
                    }
                };

            },
            template: [
                '<div class="input-group">',
                    '<input type="text" readonly="true" style="background:#fff" name="{{name}}" class="form-control" uib-datepicker-popup="{{dateFormat}}" ng-model="internalModel" is-open="isOpen" ng-click="open($event)" ng-change="change()">',
                    '<span class="input-group-btn">',
                        '<button class="btn btn-default" ng-click="open($event)">&nbsp;<i class="glyphicon glyphicon-calendar"></i>&nbsp;</button>',
                    '</span>',
                '</div>'
            ].join('')
        }
    }

})();
<!DOCTYPE html>
<html>

  <head>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
    <script src="example.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  </head>

  <body ng-app="myExample">
    <div ng-controller="MyController">
      <p>
        Date format: {{dateFormat}}
      </p>
      <p>
        Value: {{myDate}}
      </p>
      <p>
        <my-datepicker ng-model="myDate" date-format="{{dateFormat}}"></my-datepicker>
      </p>
    </div>
  </body>

</html>