【问题标题】:Angularjs: Transform data before send with ng-resource and transformRequestAngularjs:在发送之前使用 ng-resource 和 transformRequest 转换数据
【发布时间】:2017-08-07 14:15:44
【问题描述】:

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

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

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

【问题讨论】:

    标签: angularjs ngresource


    【解决方案1】:

    天哪,我觉得自己像个白痴。你只需要这样做

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

    【讨论】:

    • 小心,这在所有情况下都不起作用,如果您检查我的 defaultToJson 的实现(来自 angular-resource),您会发现它在使用 angular.toJson 之前使用了一些条件)。所以它可能对你有用,但它不适用于所有这就是为什么我有一个更复杂的答案。
    • 好的,我会考虑的。泰
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      如果其他人遇到这种情况,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;
           })
      }
      

      【讨论】:

        【解决方案4】:

        是的。有点麻烦和丑陋,但在这里:

        // 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 函数,该函数是角度默认值。

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

        【讨论】:

        • 我会试一试的
        猜你喜欢
        • 2015-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-30
        • 2019-04-13
        • 2016-08-02
        • 2017-03-18
        相关资源
        最近更新 更多