[英]angular 1.5 $resource, how to set default action, (e.g. transformResponse) for all requests?
i have a resource like: 我有像这样的资源:
angular.module('mymodule')
.factory('someResource', someResource);
function someResource($resource) {
return $resource('/something', {}, {
find : {method: 'GET', isArray: true, transformResponse: convertFn},
create: {method: 'POST', isArray: true, transformResponse: convertFn},
update: {method: 'PUT', isArray: true, transformResponse: convertFn},
});
function convertFn(){
//...
}
}
is it possible to not to copypaste the transformResponse in every type of request? 是否可以不在每种类型的请求中都复制粘贴transformResponse? Define some default transformResponse?
定义一些默认的transformResponse吗?
possible solution just to modify the definition object by adding the property programmatically, but such solution looks hard to maintain. 可能的解决方案只是通过以编程方式添加属性来修改定义对象,但这种解决方案看起来很难维护。
angular.module('mymodule')
.factory('someResource', someResource);
function someResource($resource) {
var types = {
find : {method: 'GET', isArray: true},
create: {method: 'POST', isArray: true},
update: {method: 'PUT', isArray: true},
}
//add transform to each, es6
Object.keys(types).forEach(k => types[k].transformResponse = convertFn)
return $resource('/something', {}, types);
function convertFn(){
//...
}
}
edit 编辑
thx to georgeawg for the idea 谢谢乔治的想法
another way could be: write a wrapper function for defaults like: 另一种方法可能是:为默认值编写包装函数,例如:
angular.module('mymodule')
.factory('someResource', someResource);
function someResource($resource) {
var types = {
find : defaults({method: 'GET'}),
create: defaults({method: 'POST', isArray: false}),
update: defaults({method: 'PUT'}),
}
return $resource('/something', {}, types);
function convertFn(){
//...
}
function defaults(opts) {
return Object.assign({
isArray: false,
transformResponse: convertFn
}, opts)
}
}
is there some cleaner solution for it? 是否有一些更清洁的解决方案?
How about: 怎么样:
angular.module('mymodule')
.factory('someResource', someResource);
function someResource($resource) {
return $resource('/something', {}, {
find : action('GET'),
create: action('POST'),
update: action('PUT')
});
function action(method) {
return { method: method,
isArray: true,
transformResponse: convertFn
};
}
function convertFn(){
//...
}
}
Since the $resource
uses the $http
service under the hood, a response interceptor can transform responses: 由于
$resource
在$http
使用$http
服务,因此响应拦截器可以转换响应:
app.config(function($httpProvider) {
$httpProvider.interceptors.push(function() {
return {
'request': function(config) {
//
},
'response': function(response) {
if (response.config.url.startsWith("/something") {
response.data = convertFn(response.data);
};
return response;
function convertFn(data) {
//return new data
}
}
});
});
Have you looked at angular $http interceptors ? 您是否看过有角度的$ http拦截器 ? ngResource would honor a response interceptor function.
ngResource将采用响应拦截器功能。 Here's a post that details usage.
这是详细说明用法的帖子 。
It is possible to have a very generic base $resource and inherit it. 可以有一个非常通用的基础$ resource并继承它。
I found the answer on a SO post that i can't found anymore. 我在找不到的SO帖子上找到了答案。 If someone found it edit my post to add it.
如果有人找到它,请编辑我的帖子以添加它。
Here is the code that I use : 这是我使用的代码:
angular.baseResourceServiceMaker = function(service){
return ['$injector', '$resource', 'TypeService', '$http', '_', 'BackEndpoint', 'Utils',
function($injector, $resource,TypeService, $http, _, BackEndpoint, Utils){
this.restUrl = BackEndpoint+'/rest/';
this.baseName = '';
this.resource = null;
// 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]';
}
this.defaultToJson = function(d) {
return isObject(d) && !isFile(d) && !isBlob(d) && !isFormData(d) ? angular.toJson(d) : d;
};
this.typeServiceProcessData = function(d){
return TypeService.processData(d);
};
this.typeServiceProcessJsData = function(d){
return TypeService.processJsData(d);
};
this.generateTransformRequestFn = function(mapKeyValues){
return function(data){
var object = {};
_.forEach(_.keys(mapKeyValues), function(key){
Utils.setAttributeValue(object, key, Utils.getAttributeValue(data, mapKeyValues[key]));
});
return object;
}
};
this.addedMethods = {};
// use of resource will be internal, to handle transformation of data
// and so on...
this.getResource = function(){
if(this.resource == null){
var baseResourceUrl = this.restUrl + this.baseName + '/';
var baseResourceMethods = {
'get': {method:'GET', transformResponse:[$http.defaults.transformResponse[0], this.typeServiceProcessData],
url:baseResourceUrl+':id'},
'create': {method:'POST', url:baseResourceUrl, transformRequest:[this.typeServiceProcessJsData, this.defaultToJson]},
'update' : {method:'PUT', transformRequest:[this.typeServiceProcessJsData, this.defaultToJson]},
'search': {method:'GET', isArray:true, transformResponse:[$http.defaults.transformResponse[0], this.typeServiceProcessData],
url:baseResourceUrl+'search/(:search)/:offset/:limit/:order',
params: {offset:0, limit:50, order:"creationDate=asc"}
},
'custom_search': {method:'GET', isArray:true, transformResponse:[$http.defaults.transformResponse[0], this.typeServiceProcessData],
url:baseResourceUrl+':prefix/search/(:search)/:offset/:limit/:order',
params: {search:'pk=gt=0',offset:0, limit:50, order:"creationDate=asc"}
},
'list': {method:'GET', isArray:true, transformResponse:[$http.defaults.transformResponse[0], this.typeServiceProcessData],
url:baseResourceUrl+'search/(pk=gt=0)/0/50/creationDate=asc'
},
'delete': {method:'DELETE'}
};
_.forEach(_.keys(this.addedMethods), function(key){
baseResourceMethods[key] = this.addedMethods[key];
}, this)
this.resource = $resource(baseResourceUrl+':id',
{id:'@pk'}, baseResourceMethods
);
}
return this.resource;
};
this.get = function(id){
this.getResource().get({id:id});
};
this.create = function(data){
this.getResource().create(data);
};
this.update = function(data){
this.getResource().update(data);
};
this.search = function(searchQuery){
this.getResource().search({search:searchQuery});
};
this.searchPaginate = function(searchQuery, offset, limit){
this.getResource().search({search:searchQuery, offset:offset, limit:limit});
};
this['delete'] = function(id){
this.getResource()['delete']({id:id});
};
// Finishes the other injections
$injector.invoke(service, this);
}];
};
Some comments about this code : 关于此代码的一些注释:
Example of usage : 用法示例:
.service('ArticleService',angular.baseResourceServiceMaker(['$http', function($http){
this.baseName = 'article';
var baseResourceUrl = this.restUrl + this.baseName + '/';
this.addedMethods.root ={
method:'GET', isArray:true,
transformResponse:[$http.defaults.transformResponse[0], this.typeServiceProcessData],
url:baseResourceUrl+'root'
};
}]))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.