Angular bootstrap datepicker日期格式不格式化ng-model值

问题描述 投票:62回答:13

我在角度应用程序中使用bootstrap日期选择器。然而,当我从该日期选择器中选择一个日期选择器时,我已经更新了绑定的ng-model,我想要一个日期格式为'MM / dd / yyyy'的ng-model。但它每次都像这样约会

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

代替

02/04/2009

我为同一个qazxsw poi创造了一个plunker

我的Html和控制器代码如下所示

plunkr link

角度控制器

<!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>

在此先感谢您审核我的问题。

UPDATE

我在下面调用方法来发布我的数据,VAR是大小为900的数组,其中包含日期选择器变量。

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';
};
angularjs datepicker angular-ui angular-ui-bootstrap angular-ngmodel
13个回答
102
投票

虽然已经公布了类似的答案,但我想为我做出最简单,最干净的解决方案。假设您正在使用AngularUI日期选择器并且ng-Model的初始值没有被格式化,只需将以下指令添加到您的项目即可解决问题:

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

我在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(); } } }); 找到了这个解决方案,因此所有的功劳归于那边的人们。


0
投票

定义一个解决bug的新指令并不是很理想。

由于日期选择器正确显示更晚的日期,因此一个简单的解决方法可能是将模型变量首先设置为null,然后在一段时间后设置为当前日期:

<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 />

0
投票

datepicker(和datepicker-popup)指令要求ng-model是Date对象。这是记录$scope.dt = null; $timeout( function(){ $scope.dt = new Date(); },100);

如果您希望ng-model是特定格式的字符串,则应创建包装器指令。这是一个例子(here):

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('')
        }
    }

})();

0
投票

在检查了上面的答案之后,我想出了这个并且它完美地运行而无需在标记中添加额外的属性

<!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>

0
投票

最后我解决了上述问题。 angular-strap具有与我期望的完全相同的功能。只需应用angular.module('app').directive('datepickerPopup', function(dateFilter) { return { restrict: 'EAC', require: 'ngModel', link: function(scope, element, attr, ngModel) { ngModel.$parsers.push(function(viewValue) { return dateFilter(viewValue, 'yyyy-MM-dd'); }); } } }); ,我就得到了以给定格式更新ng-model的预期行为。

date-format="MM/dd/yyyy" date-type="string"

这是工作plunk <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>


23
投票

您可以使用$解析器,如下所示,这为我解决了它。

Github AngularUI issues

HTML:

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

13
投票

我遇到了同样的问题,经过几个小时的记录和调查,我修复了它。

事实证明,这是第一次在日期选择器中设置值,$ viewValue是一个字符串,因此dateFilter按原样显示它。我所做的就是将其解析为Date对象。

在ui-bootstrap-tpls文件中搜索该块

<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>

并将其替换为:

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

    updateCalendar();
  };

希望这会有所帮助:)


9
投票

通过 ngModel.$render = function() { ngModel.$viewValue = new Date(ngModel.$viewValue); var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : ''; element.val(date); updateCalendar(); }; 指定的format只是显示日期的格式。底层的datepicker-popup是一个Date对象。试图显示它将显示它是默认的,符合标准的表示。

您可以在视图中使用ngModel过滤器显示它,或者,如果您需要在控制器中解析它,您可以在控制器中注入date并将其称为$filter。另见$filter('date')(date, format)


5
投票

在datepicker指令中选择值后,您可以使用格式化程序。例如

date filter docs

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


4
投票

已经写了这么多答案,这是我的看法。

使用Angular 1.5.6和ui-bootstrap 1.3.3,只需在模型上添加它即可完成。

LINK

注意:仅当您担心日期落后1天并且没有受到额外时间T00:00:00.000Z的困扰时,请使用此选项

更新了Plunkr:

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


3
投票

所有提议的解决方案对我都不起作用,但最接近的解决方案来自@Rishii。

我正在使用AngularJS 1.4.4和UI Bootstrap 0.13.3。

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

1
投票

我可以通过在JSP文件中添加以下代码来解决这个问题。现在模型和UI值都相同。

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

1
投票

更改ng-model的默认日期格式的步骤

对于不同的日期格式,请在此处检查jqueryui datepicker日期格式值,例如我使用了dd / mm / yy

创建angularjs指令

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

写dateFilter函数

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

在html页面中写入ng-model属性

function dateFilter(val,format) {
    return $.datepicker.formatDate(format,val);
}
© www.soinside.com 2019 - 2024. All rights reserved.