【问题标题】:Convert AJAX date to Javascript date for use with ng-model将 AJAX 日期转换为 Javascript 日期以用于 ng-model
【发布时间】:2014-06-14 03:49:39
【问题描述】:

我在服务中使用 $http.get 来获取 JSON 数据。返回的 JSON 中我的对象属性之一是 AngularJS 未解析的日期。我需要将此属性绑定到日期字段,我目前正在通过在获取 AJAX 数据后手动将 JSON 字符串转换为 javascript 日期来解决它,如下所示

app.service('MainService', function(){
  var self = this;
  self.jsonDate = null;
  self.parsedDate = null;

  // this function will get JSON data from an API in production
  self.getData = function(){
    var jsonData = "2014-06-13T16:00:00";

    // Angular does not convert my JSON data properties into dates
    self.jsonDate = jsonData;

    // I can work around this by forcing my dates to be parsed
    self.parsedDate = moment(jsonData).toDate();
  }
});

有没有更清洁的方法来做到这一点?我构建了一个将字符串转换为日期的过滤器

app.filter('stringToDate', function () {
    return function (input) {
        if (!input)
            return null;

        var date = moment(input);
        return date.isValid() ? date.toDate() : null;
    };
});

如果我使用它,过滤器效果很好,如下所示

<span ng-bind="service.jsonDate | stringToDate | date:'MM/dd/yy'"></span>

但如果我尝试将它与 ng-model 一起使用,它就不起作用,如下所示

<input type="date" ng-model="service.jsonDate | stringToDate"/>

过滤器可以与 ng-model 一起使用,还是我需要坚持手动将属性转换为日期?我这里有一个 plunker 来演示我当前的代码

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

【问题讨论】:

  • 使用自定义指令选项更新答案。

标签: json angularjs momentjs


【解决方案1】:

Plunker Demo Here

有几种方法可以做到这一点:

  1. 使用 ng-init 中的过滤器初始化一个作用域变量,然后将 ng-model 绑定到作用域变量。

    <body ng-controller="MainCtrl" ng-init="mydate = (service.jsonDate | stringToDate)">
        <label>Raw JSON Date</label>
        <input type="date" data-ng-model="service.jsonDate"/><br/><br/>
    
        <label>Parsed JSON date</label>
        <input type="date" data-ng-model="mydate"/>
     </body>
    
  2. 使用$filter 服务手动调用控制器中的stringToDate 过滤器:

    app.controller('MainCtrl', function($scope, $filter, MainService) {
        $scope.service = MainService;
    
        // fetch data from service
        $scope.service.getData();
    
        $scope.parsedDate = $filter('stringToDate')(MainService.jsonDate);
    
    });
    

    然后将变量绑定到你的ng-model:

    <input type="date" data-ng-model="parsedDate"/>
    

    [编辑]

  3. 使用custom directive,它依赖于原始 JSON 的 ng-model。添加格式化程序将模型转换为日期字符串;以及将日期字符串转换回模型的解析器。这种方法的优点是保持了双向模型绑定。当您使用有效的日期字符串更新文本框时,它会自动更新原始 JSON 模型(反之亦然)。

在 plunker 示例中,尝试输入有效的日期字符串,并注意模型如何自动更改。

指令:

   app.directive('jsonDate', function($filter) {
      return  {
          restrict: 'A',
          require: 'ngModel',
          link: function (scope, element, attrs, ngModel) {

             //format text going to user (model to view)
             ngModel.$formatters.push(function(value) {
                var date = $filter('stringToDate')(value);
                return date.toString();
             });

             //format text from the user (view to model)
             ngModel.$parsers.push(function(value) {
                var date = new Date(value);
                if (!isNaN( date.getTime())) { 
                   return moment(date).format();
                }
             });
         }
     }

HTML:

 <input type="date" data-ng-model="service.jsonDate" json-date/>

最后一个示例允许您将 ngModel 绑定到 json 日期字符串并让它显示格式化的日期。当用户输入一个有效的格式化日期时,它会自动更新其绑定的 json 日期字符串模型

【讨论】:

  • 感谢您详细解答。虽然有一个查询,但我也在尝试过去几个小时的示例 3,但它不起作用,加载 html 后它不显示日期。我访问了你的 plunker,它也不再显示日期了。
  • 在您的 plunker 上,当 .html 页面在浏览器上加载时,我希望它显示日期,但为什么不是这样?
猜你喜欢
  • 2010-12-18
  • 2021-06-07
  • 1970-01-01
  • 2010-12-25
  • 2012-06-05
  • 2017-04-15
  • 2020-03-19
  • 2016-12-17
  • 2019-06-14
相关资源
最近更新 更多