角度资源创建日期对象

时间:2014-02-02 11:08:59

标签: javascript angularjs date

我正在使用$ resource来操纵我的数据。我想把它们转换成日期对象时将它们转换成日期对象。它只是使用datepicker等更容易。

我的工厂:

AppFactories.factory("Books", ['$resource' ,function($resource){

  return $resource(
        "/books/:id",
        {id: "@id" },
        {
            "update": {method: "PUT", isArray: true },
            "save": {method: "POST", isArray: true },

        }
    );

}]);

我可以在工厂内创建一个函数,以便在发布/更新时将日期从数据库转换为日期对象,反之亦然吗?

将它集成到工厂非常好,以便我可以重复使用它。

4 个答案:

答案 0 :(得分:12)

而不是在每个资源上执行此操作,您可以将其应用于基础$ http,如更详细的描述here

app.config(["$httpProvider", function ($httpProvider) {
     $httpProvider.defaults.transformResponse.push(function(responseData){
        convertDateStringsToDates(responseData);
        return responseData;
    });
}]);

答案 1 :(得分:10)

$resource操作对象可以有一个名为interceptor的属性,允许您为此特定操作定义interceptor对象(like with $http interceptors)。您可以为此拦截器定义responseresponseError属性。这样,您可以为资源提供的操作定义一些日期解析功能:

function parseResponseDates(response) {
  var data = response.data, key, value;
  for (key in data) {
    if (!data.hasOwnProperty(key) && // don't parse prototype or non-string props
        toString.call(data[key]) !== '[object String]') continue;
    value = Date.parse(data[key]); // try to parse to date
    if (value !== NaN) data[key] = value;
  }
  return response;
}

return $resource('/books/:id', {id: '@id'},
  {
    'update': {
      method: 'PUT', 
      isArray: true, 
      interceptor: {response: parseResponseDates}
    },
    ....
  }
);

希望这有帮助!

答案 2 :(得分:4)

我想使用Angular.js的ngResource($resource),但我也希望我的日期解析不会干扰$http中的任何其他内容,并且操作的transformResponse选项似乎更多适合interceptor选项。 @ jakee的parseResponseDates很好,因为它是通用的,但它比我想要的更强大;我确切地知道我的模型中哪些字段可以是日期,我只想将这些字段解析为日期。

文档说默认transformResponse只是angular.fromJson,但这并不完全正确;它还会在运行)]}',\nhttp.js source reference)之前删除JSON漏洞保护前缀angular.fromJson。由于$resource不会轻易公开每个操作的transformResponse数组,因此您必须手动扩展默认transformResponse,方法是注入$http然后调用$http.defaults.transformResponse.concat(your_transformer)。在我的示例中,我到达的解决方案看起来像这样:

AppFactories.factory("Books", function($resource, $http) {
  var raiseBook = function(book) {
    // "created_at" is declared as NOT NULL in the database
    book.created_at = new Date(book.created_at);
    // "completed_at" is a NULL-able field
    if (book.completed_at) {
      book.completed_at = new Date(book.completed_at);
    }
    return book;
  };

  var raiseBooks = function(books) {
    return books.map(raiseBook);
  };

  return $resource("/books/:id", {
    id: "@id"
  }, {
    update: {
      method: "PUT",
      isArray: true,
      // some_array.concat(...) creates and returns a new Array,
      //   without modifying the original some_array Array
      transformResponse: $http.defaults.transformResponse.concat(raiseBooks),
    },
    save: {
      method: "POST",
      isArray: true,
      transformResponse: $http.defaults.transformResponse.concat(raiseBooks),
    },
  });
});

请注意Date.parse(...)返回一个数字(自UNIX纪元以来的毫秒数),因此,如果这是您想要的,则必须更改new Date(...)次调用。但由于原始问题需要日期对象,new Date(...)可能就是你想要的。

答案 3 :(得分:2)

我采用了@chbrown的答案,并提供了角度服务,以便在我们需要动态更新ng-resource请求/响应日期的任何情况下使用。

这是gist

使用示例:

var Session = $resource('/api/sessions/:id', {id: '@id'}, {
  query: {
    method: 'GET',
    isArray: true,
    transformResponse: dateTransformer.transformResponse.toDate(['start', 'end'])
  },
  update: {
    method: 'PUT',
    transformRequest: dateTransformer.transformRequest.toLocalIsoString(['start', 'end'])
  }
});

在Session.query()字段之后,返回的资源对象中的'start'和'end'将是JS Date对象。  会话之后。$ update()服务器将收到JSON,其中JS Date对象在字段'start'和'end'中  将只是没有时区的ISO格式的字符串。

支持的转换器:toDate,toLocalIsoString,toZonedIsoString。

此服务使用moment.js进行日期解析和格式化,因为本机JS Date不支持  没有时区的日期(它们总是被解析为UTC + 0)。

Lodash也用于对象操作。