我正在使用$ resource来操纵我的数据。我想把它们转换成日期对象时将它们转换成日期对象。它只是使用datepicker等更容易。
我的工厂:
AppFactories.factory("Books", ['$resource' ,function($resource){
return $resource(
"/books/:id",
{id: "@id" },
{
"update": {method: "PUT", isArray: true },
"save": {method: "POST", isArray: true },
}
);
}]);
我可以在工厂内创建一个函数,以便在发布/更新时将日期从数据库转换为日期对象,反之亦然吗?
将它集成到工厂非常好,以便我可以重复使用它。
答案 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)。您可以为此拦截器定义response
和responseError
属性。这样,您可以为资源提供的操作定义一些日期解析功能:
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
,但这并不完全正确;它还会在运行)]}',\n
(http.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也用于对象操作。