Angular.js和HTML5dateinput值 – 如何让Firefox在dateinput中显示可读的date值?

我有一个HTML5dateinput,我希望它的值默认设置为我的模型中的date属性的值。 我不太关心格式化,因为无论如何,基于我的语言环境,Chrome似乎决定了我的格式,但理想的格式是dd/MM/yyyy

小提琴

这是我如何设置我的input:

 <input type="date" ng-model="date" value="{{ date | date: 'yyyy-MM-dd' }}" /> 

这在Chrome上正常工作,我默认看到以下内容:

Chrome显示日期的格式化值

(我仍然不明白为什么必须在yyyy-MM-dd给出这个值,如果Chrome仍然根据我的语言环境来格式化它,但这是一个不同的问题。)

我的问题是Firefox没有按照我指定的方式显示date的值。 我认为这与将input绑定到date模型有关,因为我可以在value属性中指定几乎任何string,并且默认情况下仍会在input中看到长datestring:

Firefox显示日期字符串

如果我从input标签中删除ng-model="date" ,Firefox会很好地显示我给它的任何值。 我不认为一个input的模型实际上对其默认值有任何影响?

我知道dateinput不被普遍支持,但看到它应该回落在一个简单的文本input,我不明白为什么它的值不会简单地2013-08-05 ,由angular度的datefilter指定。

那么,如何让Firefox在dateinput中接受我的格式化值呢?


注意在用户完成编辑之后,我将执行validation并将每个dateinput值转换为适当的Date对象。 不知道这是否与问题相关,但是为了防万一,为了date转换在input格式显然需要保持一致,在所有浏览器中都是一样的。 当然,Chrome会为我决定input格式,这是有问题的。

问题在于ng-model存在时 , value被忽略 。

目前不支持type="date" Firefox会将所有的值转换为string。 由于你(理所当然地)要date是一个真正的Date对象,而不是一个string,我认为最好的select是创build另一个variables,例如dateString ,然后链接两个variables:

 <input type="date" ng-model="dateString" /> 
 function MainCtrl($scope, dateFilter) { $scope.date = new Date(); $scope.$watch('date', function (date) { $scope.dateString = dateFilter(date, 'yyyy-MM-dd'); }); $scope.$watch('dateString', function (dateString) { $scope.date = new Date(dateString); }); } 

小提琴

实际结构仅用于演示目的。 你最好创build自己的指令,特别是为了:

  • 允许yyyy-MM-dd以外的格式,
  • 能够使用NgModelController#$formattersNgModelController#$formatters ,而不是人为的dateStringvariables(请参阅有关此主题的文档 )。

请注意,我使用了yyyy-MM-dd ,因为它是JavaScript Date对象直接支持的格式。 如果你想使用另一个,你必须自己进行转换 。


编辑

这是一个制定干净指示的方法:

 myModule.directive( 'dateInput', function(dateFilter) { return { require: 'ngModel', template: '<input type="date"></input>', replace: true, link: function(scope, elm, attrs, ngModelCtrl) { ngModelCtrl.$formatters.unshift(function (modelValue) { return dateFilter(modelValue, 'yyyy-MM-dd'); }); ngModelCtrl.$parsers.unshift(function(viewValue) { return new Date(viewValue); }); }, }; }); 

小提琴

这是一个基本的指令,还有很大的改进空间,例如:

  • 允许使用自定义格式而不是yyyy-MM-dd
  • 检查用户input的date是否正确。

为什么这个值必须在yyyy-MM-dd中给出?

根据HTML 5的inputtypes=date规范 ,该值必须采用yyyy-MM-dd格式,因为它采用RFC3339中指定的有效full-date格式作为

 full-date = date-fullyear "-" date-month "-" date-mday 

由于指令input不支持datetypes,因此与Angularjs无关。

如何让Firefox在dateinput中接受我的格式化值?

FF不支持至less达到版本24.0的datetypes的input。 你可以从这里得到这个信息。 所以现在,如果你使用types为FF的dateinput,那么文本框就会接受你传入的任何值。

我的build议是你可以使用Angular-ui的Timepicker ,不要使用dateinput的HTML5支持。

你可以使用这个,它工作正常:

 <input type="date" class="form1" value="{{date | date:MM/dd/yyyy}}" ng-model="date" name="id" validatedateformat data-date-format="mm/dd/yyyy" maxlength="10" id="id" calendar maxdate="todays" ng-click="openCalendar('id')"> <span class="input-group-addon"> <span class="glyphicon glyphicon-calendar" ng-click="openCalendar('id')"></span> </span> </input> 

就我而言,我已经解决了这个问题:

 $scope.MyObject = // get from database or other sources; $scope.MyObject.Date = new Date($scope.MyObject.Date); 

和inputtypes的date是好的

我用过ng-change:

 Date.prototype.addDays = function(days) { var dat = new Date(this.valueOf()); dat.setDate(dat.getDate() + days); return dat; } var app = angular.module('myApp', []); app.controller('DateController', ['$rootScope', '$scope', function($rootScope, $scope) { function init() { $scope.startDate = new Date(); $scope.endDate = $scope.startDate.addDays(14); } function load() { alert($scope.startDate); alert($scope.endDate); } init(); // public methods $scope.load = load; $scope.setStart = function(date) { $scope.startDate = date; }; $scope.setEnd = function(date) { $scope.endDate = date; }; } ]); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div data-ng-controller="DateController"> <label class="item-input"> <span class="input-label">Start</span> <input type="date" data-ng-model="startDate" ng-change="setStart(startDate)" required validatedateformat calendar> </label> <label class="item-input"> <span class="input-label">End</span> <input type="date" data-ng-model="endDate" ng-change="setEnd(endDate)" required validatedateformat calendar> </label> <button button="button" ng-disabled="planningForm.$invalid" ng-click="load()" class="button button-positive"> Run </button> </div <label class="item-input"> <span class="input-label">Start</span> <input type="date" data-ng-model="startDate" ng-change="setStart(startDate)" required validatedateformat calendar> </label> <label class="item-input"> <span class="input-label">End</span> <input type="date" data-ng-model="endDate" ng-change="setEnd(endDate)" required validatedateformat calendar> </label> 

检查MEAN.JS(Angular.js,bootstrap,Express.js和MongoDb)的完整function指令

基于@Blackhole的回应,我们刚刚完成了与mongodb和express的使用。

它将允许您保存和加载mongoose连接器的date

希望能帮助到你!!

 angular.module('myApp') .directive( 'dateInput', function(dateFilter) { return { require: 'ngModel', template: '<input type="date" class="form-control"></input>', replace: true, link: function(scope, elm, attrs, ngModelCtrl) { ngModelCtrl.$formatters.unshift(function (modelValue) { return dateFilter(modelValue, 'yyyy-MM-dd'); }); ngModelCtrl.$parsers.push(function(modelValue){ return angular.toJson(modelValue,true) .substring(1,angular.toJson(modelValue).length-1); }) } }; }); 

JADE / HTML:

 div(date-input, ng-model="modelDate") 

如果使用Angular Material Design,则可以在那里使用datepicker组件,这可以在Firefox,IE等中使用。

https://material.angularjs.org/latest/demo/datepicker

公平的警告 – 个人的经验是,这是有问题的,似乎目前正在重新工作。 看这里:

https://github.com/angular/material/issues/4856