Angular bootstrap datepicker 日期格式不格式化 ng-model 值
Posted
技术标签:
【中文标题】Angular bootstrap datepicker 日期格式不格式化 ng-model 值【英文标题】:Angular bootstrap datepicker date format does not format ng-model value 【发布时间】:2014-08-03 14:53:40 【问题描述】:我在我的 Angular 应用程序中使用引导日期选择器。但是,当我从我绑定的基础 ng-model 的日期选择器中选择一个日期时,我希望该 ng-model 采用一种日期格式“MM/dd/yyyy”。但它每次都会像这样约会
"2009-02-03T18:30:00.000Z"
而不是
02/04/2009
我为相同的plunkr link 创建了一个 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.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';
;
提前感谢您查看我的问题。
更新
我正在调用以下方法来发布我的数据,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;
【问题讨论】:
哈哈,幸运的是你我的甚至没有绑定到我的 ng-model 我复制了你的代码,它对我有用。 :) 【参考方案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 issues 中找到了这个解决方案,因此所有功劳都归于那里的人。
【讨论】:
这需要比接受的答案更高的投票率,尤其是在使用 bower 或 pkg 管理器获取 angular-ui 时。效果很好,我可以不理会 angular-ui.js。 我同意 - 这个答案要好得多,尤其是在使用 nuget 包中的预压缩代码时。手动编辑意味着您必须在每次更新代码时重新创建它们,而这是永久且简单的 - 如果此错误得到修复,您只需删除指令。这是迄今为止更好的答案。 我已经玩了几天我的 sql 日期类型、格式等,以使这件事起作用。这个答案立即解决了它。阿格格!哈哈,我再也回不来了…… 为我工作。非常感谢! 在 angular 1.4 和 angular-bootstrap 0.13.3 上对我不起作用。 this answer 做到了!【参考方案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>
【讨论】:
这是 Angular 1.4 和 angular bootstrap .13 的修复,上面那个不起作用 您的解决方案有效,而不是投票最高的解决方案。 Angular1.4.7 UI-bootstrap 0.14.3【参考方案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();
;
希望这会有所帮助:)
【讨论】:
if (!ngModel.$viewValue)ngModel.$viewValue = new Date();否则 ngModel.$viewValue = new Date(ngModel.$viewValue); 在github.com/angular-ui/bootstrap/pull/2943 中稍好修复,处理值为null
时的情况。
如果您使用的是 bower 或其他包管理器中的 angular-bootstrap,这将不起作用。不建议编辑库本身。【参考方案4】:
通过datepicker-popup
指定的format
只是显示日期的格式。底层 ngModel
是一个 Date 对象。尝试显示它会将其显示为默认的、符合标准的 rapresentation。
您可以通过在视图中使用date
过滤器来显示它,或者,如果您需要在控制器中对其进行解析,您可以在控制器中注入$filter
并将其称为$filter('date')(date, format)
.另请参阅date filter docs。
【讨论】:
是的,我明白你的意思。但是我在屏幕上动态生成日期选择器,所以没有地方解析那个 ng-model。 好的,但是您想在哪里使用日期选择器中的ngModel
?如果要在 UI 中显示,请使用 date
。如果它在服务/控制器中,只需使用$filter('date')
。
实际上我的 ngModel 有很长的数组,正在发布到 REST 服务。
现在我想,我应该制作自己的指令,该指令将在模板中包含 datepicker-popup 并将底层日期对象解析为所需的格式。
但是您最终也会在自己的指令中使用过滤器或格式化程序,我看不出您将如何避免这种情况。你能准备一个小提琴来显示你是如何使用日期选择器中的日期的吗?【参考方案5】:
您可以在 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.
【讨论】:
是的,这就是我在上述答案中的链接转换中所说的。但是我需要使用解析器来更新底层 ng-model,如果我要实现更新 ng-model 的解析器,它可能会再次调用 date-picker 指令来更新日期。我不确定,但我会尝试一下。 我终于找到了解决方案。看我的回答***.com/questions/24198669/… 你在正确的轨道上,但我相信它应该是 ctrl.$parsers.push 因为他希望他的 ng-model 存储修改后的值。【参考方案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>
【讨论】:
在我看来,您的问题与上面提到的问题完全不同(问题)。上面的问题状态有问题,而后端模型需要一些其他类型而不是日期,并且您想要的似乎在 UI 上显示了不同的内容。请记住,您的解决方案后端模型值将是相同的日期对象。【参考方案9】:修改ng-model默认日期格式的步骤
对于不同的日期格式,请在此处检查 jqueryui 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 dateFilter(val,format)
return $.datepicker.formatDate(format,val);
在html页面中写入ng-modal属性
<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】:datepicker(和 datepicker-popup)指令要求 ng-model 是一个 Date 对象。这记录在here。
如果您希望 ng-model 成为特定格式的字符串,您应该创建一个包装器指令。这是一个例子(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)"> <i class="glyphicon glyphicon-calendar"></i> </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>
【讨论】:
【参考方案11】:定义一个新指令来解决一个错误并不是很理想。
由于日期选择器正确显示较晚的日期,一个简单的解决方法可能是先将模型变量设置为空,然后再设置为当前日期:
$scope.dt = null;
$timeout( function()
$scope.dt = new Date();
,100);
【讨论】:
【参考方案12】:在检查了上述答案后,我想出了这个,它完美地工作,而无需为您的标记添加额外的属性
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');
);
);
【讨论】:
【参考方案13】:终于解决了上述问题。 angular-strap 具有我所期望的完全相同的功能。只需应用date-format="MM/dd/yyyy" date-type="string"
,我就得到了以给定格式更新 ng-model 的预期行为。
<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 link
【讨论】:
所以你必须切换到 angular-strap 而不是 ui.bootstrap? ui.bootstrap 中没有类似的选项吗? @MattPileggi 其实我没有找到。如果您发现与 ui.bootstrap 相同的内容并在此处分享,我将不胜感激。 此解决方案需要 angular-strap 的日期选择器。它伴随着其他问题。 @SergiuParaschiv 但就我而言,它运行良好。你可以参考plunker。 您没有回答原始问题 - 如何使用 angular-ui bootstrap 进行这项工作。您应该接受下面克里斯蒂娜的回答,因为它实际上回答了原始问题。以上是关于Angular bootstrap datepicker 日期格式不格式化 ng-model 值的主要内容,如果未能解决你的问题,请参考以下文章
我如何将 Bootstrap 3 Datepicker 自定义为仅没有时间戳的日期
在 angular.bootstrap 之后添加 Angular 模块
如何在 Angular 1.5 中将 Angular 组件与 ui.bootstrap.modal 一起使用?