因此,首先为了拦截所有字符串日期并将其转换为 javascript 日期,我们需要 Angular 来进行拦截和替换。为此,我们可以在 httpProvider 上使用拦截器,以确保我们的代码在执行任何其他代码之前在所有返回的 http 响应上运行。
var app = angular.module('app');
app.config(configureProviders);
configureProviders.$inject = ['$httpProvider'];
function configureProviders($httpProvider) {
configureHttp($httpProvider);
}
function configureHttp(httpProvider) {
// add all http interceptors
httpProvider.interceptors.push('dateDeserialiserInterceptor');
}
好的,现在我们已经注册了拦截器,但是我们需要一些代码来使它工作:
(function () {
var module = angular.module('myApp.interceptors');
module.factory('dateDeserialiserInterceptor', function () {
function convertDateStringsToDates(input) {
// Ignore things that aren't objects.
if (typeof input !== "object") return input;
for (var key in input) {
if (!input.hasOwnProperty(key)) continue;
var value = input[key];
// Check for string properties which look like dates.
if (typeof value === "string" && (moment(value, moment.ISO_8601).isValid())) {
input[key] = moment(value, moment.ISO_8601).toDate();
} else if (typeof value === "object") {
// Recurse into object
convertDateStringsToDates(value);
}
}
};
return {
response: function (response) {
convertDateStringsToDates(response);
return response;
}
};
});
})();
所以上面的代码最初是从某个地方从互联网上取下来的,并且有一个手动的正则表达式比较。regEx 被描述为符合 ISO 8601,但我发现了许多不符合 ISO 8601 的示例。这现在依赖于开源库 momentJs来确定日期是否符合 ISO 8601并进行转换。如果日期不合规,则简单地返回字符串值。ISO 8601 是一个很好的使用标准(因为它涵盖了多种情况),并且比硬编码任何预期的特定格式要好得多,这可能会导致您走上“哦……它错过了”的道路。
目前,这正在解析所有返回的响应对象值以获取潜在日期。我考虑通过使用我们期望的日期的响应属性显式标记请求来改进这一点。这样我们就不必尝试解析所有内容(这很慢),也不必冒我们不想转换的东西被转换的风险。然而,这种方法有点混乱,会乱扔很多请求。我现在喜欢这种方法,它似乎有效。很高兴它得到改进!