Angularjs:在使用ng-resource和transformRequest发送之前转换数据

时间:2016-01-12 13:10:07

标签: angularjs ngresource

我想在通过ng-resource将数据发送到服务器之前更改一些数据。我像这样使用tranformRequest-Function:

    update: {
        method: 'PUT',
        transformRequest: function (data) {
             // modify data then
             return data;
        }
    }

我可以通过这种方式修改数据,但在请求中我的数据始终是序列化的。我想把我的数据保存为JSON。这是可以使用transformRequest还是在控制器中完成。我宁愿在服务中这样做。请求帮助

4 个答案:

答案 0 :(得分:4)

我觉得自己像个白痴。你只需要做

update: {
    method: 'PUT',
    transformRequest: function (data) {
         // modify data then
         return angular.toJson(data);
    }
}

答案 1 :(得分:3)

以下是我在我的应用中使用的示例。 $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案例来说已经足够了。

答案 2 :(得分:0)

是的。有点麻烦和过分但这里是:

// 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-resources复制/粘贴了一些函数定义,因为它们没有在该范围内定义,也无法从角度资源外部访问。要查看为什么需要它们,请检查我定义的defaultToJson函数,它是角度默认值。

如果有人有更好的方法来复制粘贴,我也会采取一堆功能:)

答案 3 :(得分:0)

如果遇到其他人,Angular会为对象提供默认转换。 $ http服务公开defaults.transformRequest,它检查data属性是否为对象并自动将其序列化为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;
     })
}