Angularjs Angular JS-转换Json日期并将作用域应用于模型
我正在使用AngularJS创建一个简单的CRUD,并且面临一个小问题。在编辑表单时,我得到了模型中服务器返回的json字符串,我已经创建了自定义指令来格式化该日期。它格式化了日期,但没有应用范围,当我提交表单时,我会得到警报中的旧json日期 我的Js是这样的:Angularjs Angular JS-转换Json日期并将作用域应用于模型,angularjs,angularjs-directive,angularjs-scope,Angularjs,Angularjs Directive,Angularjs Scope,我正在使用AngularJS创建一个简单的CRUD,并且面临一个小问题。在编辑表单时,我得到了模型中服务器返回的json字符串,我已经创建了自定义指令来格式化该日期。它格式化了日期,但没有应用范围,当我提交表单时,我会得到警报中的旧json日期 我的Js是这样的: var myApp = angular.module('myApp', ['toaster']).controller('MyController',function($scope){ $scope.old = { ship_
var myApp = angular.module('myApp', ['toaster']).controller('MyController',function($scope){
$scope.old = { ship_date : '/Date(1359743400000)/' };
$scope.UpdateShipment = function () {
alert($scope.old.ship_date);
}
}).directive('formatDate', function () {
return {
require: 'ngModel',
scope : {'ngModel' : '='},
link: function (scope, element, attr, ngModelController) {
ngModelController.$formatters.unshift(function (valueFromModel) {
if (angular.isUndefined(valueFromModel)) {
return valueFromModel;
}
var date = new Date(parseInt(valueFromModel.substr(6)));
console.log(valueFromModel);
return date.toLocaleDateString();
});
}
};
});
.config([
$httpProvider", function($httpProvider) {
$httpProvider.interceptors.push("httpInterceptorTransformResponseService");
}
])
视图:
请提供帮助,非常感谢。当您以非角度方式操作函数时,请使用$scope.$apply()
在
ngModelController({…})
函数add$scope.$apply()之后重试代码>您需要使用$scope.$apply。请参阅此关于修改指令内的作用域。以前所有关于您需要调用$scope.apply()的答案都是正确的,但正如您所看到的,当另一个摘要/应用已经在进行中时,它可能会抛出错误,因此要安全地调用它,请使用此选项
如果(!$scope.$$phase){$scope.$apply();}
只有在没有进展的情况下才会调用它,希望它能解决您的问题。我也有类似的问题,但我用$http拦截器处理了它。您可以将日期字符串转换为javascript对象。不需要自定义指令。我认为这是一个更干净的方法
以下是示例实现:
只需从指令中删除范围定义
enter code here
要根据“stride”的答案进行构建,还可以使用拦截器来实现。在将其实现为拦截器时,需要进行一些关键更改
首先,您的.config部分如下所示:
var myApp = angular.module('myApp', ['toaster']).controller('MyController',function($scope){
$scope.old = { ship_date : '/Date(1359743400000)/' };
$scope.UpdateShipment = function () {
alert($scope.old.ship_date);
}
}).directive('formatDate', function () {
return {
require: 'ngModel',
scope : {'ngModel' : '='},
link: function (scope, element, attr, ngModelController) {
ngModelController.$formatters.unshift(function (valueFromModel) {
if (angular.isUndefined(valueFromModel)) {
return valueFromModel;
}
var date = new Date(parseInt(valueFromModel.substr(6)));
console.log(valueFromModel);
return date.toLocaleDateString();
});
}
};
});
.config([
$httpProvider", function($httpProvider) {
$httpProvider.interceptors.push("httpInterceptorTransformResponseService");
}
])
有了它,您将构建一个工厂服务来截取和转换类似于示例的数据。正则表达式有点随意,根据您通过请求实际检索的数据,您可能需要更改它
(function () {
"use strict";
angular.module("yourAppNameHere")
.factory("httpInterceptorTransformResponseService",
[
function () {
// Purpose: This interceptor is intended to convert Json strings that match the ISO8601 date format into DateTime objects.
// This is necessary in many cases because there is not an object type embedded into serialized Json that represents a DateTime object.
// There are numerous variations of this regex. Choose the one that works best for you, based on what data you expect
var regexIso8601 = /^(\d{4}|\+\d{6})(?:-(\d{2})(?:-(\d{2})(?:T(\d{2}):(\d{2}):(\d{2})\.(\d{1,})(Z|([\-+])(\d{2}):(\d{2}))?)?)?)?$/;
function convertDateStringsToDates(input) {
// Ignore things that aren't objects.
if (typeof input !== "object")
return;
for (var key in input) {
if (!input.hasOwnProperty(key))
continue;
var value = input[key];
var match;
// Check for string properties which look like dates.
if (typeof value === "string" && (match = value.match(regexIso8601))) {
var milliseconds = Date.parse(match[0])
if (!isNaN(milliseconds)) {
input[key] = new Date(milliseconds);
}
} else if (typeof value === "object") {
// Recurse into object
convertDateStringsToDates(value);
}
}
}
// declare the service
var transformResponseService = {
response: function (response) {
// convert all parsable date strings returned from the data into Date objects
convertDateStringsToDates(response.data);
return response;
}
};
return transformResponseService;
}
]);
})();
关键部分:请注意在服务声明和转换响应声明的末尾附近。拦截器的上述版本调用如下:
convertDateStringsToDates(response.data);
而不是
convertDateStringsToDates(response);
如果在使用拦截器时向函数发送response而不是response.data,那么它将解析从整个http请求返回的所有内容。这意味着,除了检索的数据外,它还将应用于http配置、头等
我遇到了一个问题,它在http请求的配置部分运行正则表达式。因为它是一个递归服务,对象被当作引用来处理,所以它进入了一个无限循环,并会溢出堆栈。很可能您只想将其应用于返回的数据,而不是配置、标题等。我试图创建一个fiddle,如果这有帮助,请在控制台中检查错误。我读过这篇文章,但情况不同。当模型被渲染时,我想这样做,不像他们将作用域绑定到EventThank的情况,这很有吸引力,还解决了一些其他问题。(y) 谢谢你的小提琴:)