繁体   English   中英

Angular.js和HTML5日期输入值 - 如何让Firefox在日期输入中显示可读日期值?

[英]Angular.js and HTML5 date input value — how to get Firefox to show a readable date value in a date input?

我有一个HTML5日期输入,我希望默认情况下将其值设置为我的模型中的日期属性的值。 我对格式化并不是太挑剔,因为Chrome似乎根据我的语言环境决定对我来说,但理想情况下格式将始终为dd/MM/yyyy

小提琴

这是我设置输入的方式:

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

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

Chrome显示日期的格式化值

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

我的问题是Firefox没有以我指定的方式显示日期的值。 我认为这与将输入绑定到date模型有关,因为我可以在value属性中指定几乎任何字符串,并且我仍然会在输入中看到默认的长日期字符串:

Firefox显示日期字符串

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

我理解普遍不支持日期输入,但看到它应该依赖于一个简单的文本输入,我不明白为什么它的值不会仅仅是2013-08-05 ,由angular的日期过滤器指定。

那么,如何让Firefox在日期输入中接受我的格式化值?


注意在用户完成编辑后,我当然会执行验证并将每个日期输入值转换为正确的Date对象。 不确定这是否与问题相关,而是将其放在那里以防万一,因为输入格式显然需要保持一致,以便日期转换在所有浏览器中都能正常工作。 当然有问题,Chrome决定我的输入格式......

问题是当存在ng-model时忽略value

Firefox目前不支持type="date" ,它会将所有值转换为字符串。 既然你(正确地)希望date是一个真正的Date对象而不是一个字符串,我认为最好的选择是创建另一个变量,例如dateString ,然后链接这两个变量:

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

小提琴

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

请注意我使用了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
  • 检查用户输入的日期是否正确。

为什么价值必须以yyyy-MM-dd给出?

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

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

与Angularjs无关,因为指令输入不支持date类型。

如何让Firefox在日期输入中接受我的格式化值?

FF不支持至少高达版本24.0的date输入类型。 您可以从这里获得此信息。 因此,就目前而言,如果您使用类型为FF的date输入,则文本框将采用您传入的任何值。

我的建议是你可以使用Angular-ui的Timepicker而不使用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);

和输入类型日期是好的

我用过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)

基于@Blackhole的回复,我们刚刚完成它与mongodb和express一起使用。

它允许您从猫鼬连接器保存和加载日期

希望能帮助到你!!

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM