为啥我在 AngularJS 中的日期输入字段会抛出类型错误?

Posted

技术标签:

【中文标题】为啥我在 AngularJS 中的日期输入字段会抛出类型错误?【英文标题】:Why is my date input field in AngularJS throwing type error?为什么我在 AngularJS 中的日期输入字段会抛出类型错误? 【发布时间】:2015-01-07 07:26:30 【问题描述】:

当我向用户显示填充的、可编辑的表单时发生错误(而不是当用户输入数据并提交时)。数据来自 mysql 的 REST/JSON 服务,如下所示:

html

<input class="form-control" type="date" name="dateInput" id="dateOfBirth" 
                   ng-model="user.dateOfBirth">

C 控制器:

.controller('EditCtrl', function ($scope, $routeParams, UserDetail, $window) 
        $scope.user = UserDetail.find(, 'id': $routeParams.id);

服务:

service.factory('UserDetail', function ($resource) 

    return $resource(
        'http://localhost:8080/ClearsoftDemoBackend/webresources/clearsoft.demo.users/:id',
        id: '@id',
    
    find: method: 'GET',

    );
);

错误:

错误:[ngModel:datefmt] 预期 2010-05-13T00:00:00-04:00 是一个日期

【问题讨论】:

输入值是字符串,不是日期。您可以调用 new Date(input.value) 来获取真实的日期对象。 在控制器中?试过了,它似乎被覆盖了......也许当一个承诺从服务返回时? 【参考方案1】:

对于数组中的日期值,可以将其用作:

    var dates = [
       id: "1" , date: "2015-04-20T11:24:20.882Z",
       id: "2" , date: "2015-05-20T11:24:20.882Z",
       id: "3" , date: "2015-06-20T11:24:20.882Z",
    ];

      function dateStringToObject (data) 
        for(var i=0; i < data.length; i++ )
          data[i].date = new Date(data[i].date);
          

        return data;
      

   dateStringToObject(dates);

【讨论】:

【参考方案2】:

AngularJS 1.3 添加到输入 [date | datetime-local ] 字段是一个新的格式化程序/解析器,用于检查模型是否为日期对象并抛出 datefmt 异常。

if (value && !isDate(value)) 
    throw $ngModelMinErr('datefmt', 'Expected `0` to be a date', value);

此问题在之前的版本中不存在,我建议在升级时考虑以避免大噩梦。

一种解决方法是使用自定义 dateFormat 指令重置默认格式化程序/解析器,并使用 momentjs 格式化、解析字符串为 Date。

define(['directives/directives','momentjs'], function(directives,momentjs) 
directives.directive('dateFormat', function() 
      return 
        require: 'ngModel',
        link: function(scope, element, attr, ngModelCtrl) 
          var format=attr.dateFormat;
          //Angular 1.3 insert a formater that force to set model to date object, otherwise throw exception.
          //Reset default angular formatters/parsers
          ngModelCtrl.$formatters.length=0;
          ngModelCtrl.$parsers.length=0;

          ngModelCtrl.$formatters.push(function(valueFromModel) 
             //return how data will be shown in input
              if(valueFromModel)
                 // For momentjs > 2.9 moment global va is not defined use momentjs instead of moment.
                  return moment(valueFromModel).format(format);
              
              else
                  return null;
          );
          ngModelCtrl.$parsers.push(function(valueFromInput) 
              if(valueFromInput)
                  //For momentjs > 2.9 moment global va is not defined use momentjs instead of moment.
                  return moment(valueFromInput,format).toDate();
              
              else 
                  return null;
          );
        
      ;
    );
);

更新 对于 momentjs > 2.9,请考虑未定义 moment 全局变量。

2.9 "Deprecation warning: Accessing Moment through the global scope is deprecated, and will be removed in an upcoming release."

对于 AMD,需要使用 momentjs 而不是 moment。即:

return momentjs(valueFromModel).format(format);

【讨论】:

在浪费了一整天之后,这个解决方案终于奏效了!!对于输入类型 datetime-local,我使用了 date-format="YYYY-MM-DDTHH:mm" 并让它在 Ionic 应用程序上运行。感谢分享。【参考方案3】:

在你的 api 中

$date = date("Y-m-d");
$new_date = date("c",strtotime($date));
echo json_encode(array("date"=>$new_date));

在你的控制器中

/* var date 
* this is value from your api
*/
$scope.date = new Date(date);

【讨论】:

【参考方案4】:

基本上它与格式无关,它需要一个 ISO 格式的有效新 Date() 对象,所以无论你得到什么响应,只要做一个新的 Date 和 angular 就会很高兴,我在解析异常消息时得到了这个按角度

https://docs.angularjs.org/error/ngModel/datefmt?p0=2015-11-24

【讨论】:

【参考方案5】:

这是因为根据 Angular,那不是一个有效的日期。 Check out the doc on input[date] 关于日期验证的说明。如果它是一个日期,它的格式应该是 YYYY-MM-DD。

【讨论】:

@vt97john 这听起来像是一个单独的问题。你应该写一个新的并包含更多的代码,这样我们就可以看到它发生了什么。 我在上面添加了更多代码。在哪里/如何正确格式化日期? 我终于让它工作了。我最初的格式化尝试失败了,因为它在服务调用返回的承诺后被覆盖。我必须在服务 ($resource) 响应上使用“transformResponse”进行格式化才能使其正常工作。查找:方法:'GET',transformResponse:函数(数据)数据=角度.fromJson(数据); data.dateOfBirth = 新日期(data.dateOfBirth);返回数据;

以上是关于为啥我在 AngularJS 中的日期输入字段会抛出类型错误?的主要内容,如果未能解决你的问题,请参考以下文章

datetime-local输入中的默认日期 - AngularJS

为啥 Erlang 中的模式匹配记录会抛出错误

允许 HTML5 日期输入中的空值 [重复]

调用 $(".myItem").dateInput() 后 angularjs 输入字段未更新

为啥来自 csv 的日期在 php 端显示为数字?

为啥 md-calendar 指令初始化为错误的日期 AngularJS?