将AJAX日期转换为Javascript日期以与ng-model一起使用

3 json angularjs momentjs

我在服务中使用$ 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();
  }
});
Run Code Online (Sandbox Code Playgroud)

这样做有更干净的方法吗?我构建了一个将字符串转换为日期的过滤器

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

        var date = moment(input);
        return date.isValid() ? date.toDate() : null;
    };
});
Run Code Online (Sandbox Code Playgroud)

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

<span ng-bind="service.jsonDate | stringToDate | date:'MM/dd/yy'"></span>
Run Code Online (Sandbox Code Playgroud)

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

<input type="date" ng-model="service.jsonDate | stringToDate"/>
Run Code Online (Sandbox Code Playgroud)

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

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

pix*_*its 6

Plunker演示在这里

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

  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>
    
    Run Code Online (Sandbox Code Playgroud)
  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);
    
    });
    
    Run Code Online (Sandbox Code Playgroud)

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

    <input type="date" data-ng-model="parsedDate"/>
    
    Run Code Online (Sandbox Code Playgroud)

    [编辑]

  3. 使用依赖于原始JSON的ng模型的自定义指令.添加格式化程序以将模型转换为日期字符串; 和解析器将日期字符串转换回模型.这种方法的优点是保持了双向模型绑定.使用有效日期字符串更新文本框时,它会自动更新原始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();
                }
             });
         }
     }
Run Code Online (Sandbox Code Playgroud)

HTML:

 <input type="date" data-ng-model="service.jsonDate" json-date/>
Run Code Online (Sandbox Code Playgroud)

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