Angularjs: преобразовывать данные перед отправкой с помощью ng-ресурса и transformRequest
Я хочу изменить некоторые данные перед отправкой их на сервер через ng-ресурс. Я использую функцию tranformRequest следующим образом:
update: {
method: 'PUT',
transformRequest: function (data) {
// modify data then
return data;
}
}
Я могу изменить данные таким образом, но в запросе мои данные всегда сериализуются. Я хочу сохранить мои данные в формате JSON. Это возможно с transformRequest или это должно быть сделано в контроллере. Я бы предпочел сделать это в сервисе. Спасибо за помощь
4 ответа
Боже, я чувствую себя идиотом. Вы просто должны сделать
update: {
method: 'PUT',
transformRequest: function (data) {
// modify data then
return angular.toJson(data);
}
}
Вот пример, который я использую в своем приложении. Абоненты $resource
методы передают простой список параметров как JSON, а transformRequest
связывает параметры в формат, ожидаемый API, который я использую.
var myServices = angular.module('myServices', ['ngResource']);
...
myServices.factory('MyServer', ['$resource', function($resource){
var formatLoginRequest = function(data) {
// input looks like: {username:"imauser", pw:"password"}
// output should be: {request: {cmd:"login", username:"imauser", pw:"password"}}
data.cmd="login";
data = {request: data};
data = angular.toJson(data);
return data;
};
...
return = $resource('https://api.server.com/', {}, {
login: {method:'POST', params:{}, isArray:false, transformRequest:formatLoginRequest },
...other methods defined here...
});
Как отмечено в другом месте, angular.toJson()
не будет правильно сериализовать все типы данных, но этого достаточно для моего случая с JSON.
В случае, если кто-то еще сталкивается с этим, Angular предоставляет преобразования по умолчанию для объектов. Служба $http предоставляет defaults.transformRequest, который проверяет, является ли свойство данных объектом, и автоматически сериализует его в JSON.
В этом конкретном случае я бы просто проверил, являются ли данные объектом, а если нет, и переопределил бы $http.defaults.transformRequest.
function appendTransform(defaults, transform) {
defaults = angular.isArray(defaults) ? defaults : [defaults];
return defaults.concat(transform);
};
update: {
method: 'PUT',
transformRequest:
appendTransform($http.defaults.transformResponse,function(data) {
data = angular.isObject(data) ? data : {data};
return data;
})
}
Да, это. Немного хлопотно и вял, но вот оно:
// from angular-resource
var toString= function() {
var value = [];
_.forEach(this, function(e) {
value.push('' + e);
});
return '[' + value.join(', ') + ']';
};
var isObject = function isObject(value) {
// http://jsperf.com/isobject4
return value !== null && typeof value === 'object';
};
var isFile = function(obj) {
return toString.call(obj) === '[object File]';
}
var isFormData = function(obj) {
return toString.call(obj) === '[object FormData]';
}
var isBlob = function(obj) {
return toString.call(obj) === '[object Blob]';
}
var defaultToJson = function(d) {
return isObject(d) && !isFile(d) && !isBlob(d) && !isFormData(d) ? angular.toJson(d) : d;
};
this.typeServiceProcessData = function(d){
//[put your code here for to change data this will be called before angular default serialization to the server]
};
this.typeServiceProcessJsData = function(d){
//[for data that come back from the server after getting parse by default angular json parsing]
};
// sample creation of a resource method, be really carefull about the order in transformResponse and transformRequest
'get': {method:'GET', transformResponse:[$http.defaults.transformResponse[0], this.typeServiceProcessData]},
'create': {method:'POST', url:baseResourceUrl, transformRequest:[this.typeServiceProcessJsData, defaultToJson]},
Это огромный код, который я сделал некоторое время назад, и я скопировал / вставил некоторые определения функций из angular-resource, потому что они не были определены в этой области и не были доступны извне angular-ресурса. Чтобы понять, зачем они нужны, проверьте функцию defaultToJson, которую я определил, это угловое значение по умолчанию.
Если у кого-то есть лучший способ скопировать и вставить эту функцию, я тоже возьму:)