可以有一个非常通用的基础 $resource 并继承它。
我在一个我再也找不到的 SO 帖子上找到了答案。如果有人发现它,请编辑我的帖子以添加它。
这是我使用的代码:
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);
}];
};
关于这段代码的一些cmets:
- 函数 isFile/isObject,... 是来自 angular.js 的 c/c,因为我保留了来自 angularJS 的 defaultTransformResponse,这个函数使用了不在我范围内的内部函数,所以我不得不抄送它。
- 我定义了默认方法 create/update/...
- 我有一个 typeService,我在其中声明了我的所有类型和字段,因此我可以自动转换类型:例如,我的服务器日期始终是时间戳,所以我在 transformResponse 中将其自动转换为 Javascript Date,而在 transformRequest 中则相反。李>
- addedMethods 用于添加其他方法。
- restUrl是所有rest服务的入口点,baseName必须由实现设置,它是资源的入口点。 BackEndPoint 是定义我的应用程序的 contextPath 的常量。
使用示例:
.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'
};
}]))