aboutsummaryrefslogtreecommitdiffstats
path: root/src/service
diff options
context:
space:
mode:
authorIgor Minar2012-02-28 17:33:54 -0800
committerIgor Minar2012-03-20 11:07:38 -0700
commit6a8749e65a7efb69a65be87605cd7d4a2df2fbb0 (patch)
tree6b691c6a8184ad4362159e9b02b1f1a6c3eea12f /src/service
parent1a5bebd927ecd22f9c34617642fdf58fe3f62efb (diff)
downloadangular.js-6a8749e65a7efb69a65be87605cd7d4a2df2fbb0.tar.bz2
refactor($resource): unify and simplify the code
Diffstat (limited to 'src/service')
-rw-r--r--src/service/resource.js164
1 files changed, 162 insertions, 2 deletions
diff --git a/src/service/resource.js b/src/service/resource.js
index 790d5ed6..3aa48e74 100644
--- a/src/service/resource.js
+++ b/src/service/resource.js
@@ -202,7 +202,167 @@
*/
function $ResourceProvider() {
this.$get = ['$http', function($http) {
- var resource = new ResourceFactory($http);
- return bind(resource, resource.route);
+ var DEFAULT_ACTIONS = {
+ 'get': {method:'GET'},
+ 'save': {method:'POST'},
+ 'query': {method:'GET', isArray:true},
+ 'remove': {method:'DELETE'},
+ 'delete': {method:'DELETE'}
+ };
+
+
+ function Route(template, defaults) {
+ this.template = template = template + '#';
+ this.defaults = defaults || {};
+ var urlParams = this.urlParams = {};
+ forEach(template.split(/\W/), function(param){
+ if (param && template.match(new RegExp("[^\\\\]:" + param + "\\W"))) {
+ urlParams[param] = true;
+ }
+ });
+ this.template = template.replace(/\\:/g, ':');
+ }
+
+ Route.prototype = {
+ url: function(params) {
+ var self = this,
+ url = this.template,
+ encodedVal;
+
+ params = params || {};
+ forEach(this.urlParams, function(_, urlParam){
+ encodedVal = encodeUriSegment(params[urlParam] || self.defaults[urlParam] || "");
+ url = url.replace(new RegExp(":" + urlParam + "(\\W)"), encodedVal + "$1");
+ });
+ url = url.replace(/\/?#$/, '');
+ var query = [];
+ forEachSorted(params, function(value, key){
+ if (!self.urlParams[key]) {
+ query.push(encodeUriQuery(key) + '=' + encodeUriQuery(value));
+ }
+ });
+ url = url.replace(/\/*$/, '');
+ return url + (query.length ? '?' + query.join('&') : '');
+ }
+ };
+
+
+ function ResourceFactory(url, paramDefaults, actions) {
+ var route = new Route(url);
+
+ actions = extend({}, DEFAULT_ACTIONS, actions);
+
+ function extractParams(data){
+ var ids = {};
+ forEach(paramDefaults || {}, function(value, key){
+ ids[key] = value.charAt && value.charAt(0) == '@' ? getter(data, value.substr(1)) : value;
+ });
+ return ids;
+ }
+
+ function Resource(value){
+ copy(value || {}, this);
+ }
+
+ forEach(actions, function(action, name) {
+ var isPostOrPut = action.method == 'POST' || action.method == 'PUT';
+ Resource[name] = function(a1, a2, a3, a4) {
+ var params = {};
+ var data;
+ var success = noop;
+ var error = null;
+ switch(arguments.length) {
+ case 4:
+ error = a4;
+ success = a3;
+ //fallthrough
+ case 3:
+ case 2:
+ if (isFunction(a2)) {
+ if (isFunction(a1)) {
+ success = a1;
+ error = a2;
+ break;
+ }
+
+ success = a2;
+ error = a3;
+ //fallthrough
+ } else {
+ params = a1;
+ data = a2;
+ success = a3;
+ break;
+ }
+ case 1:
+ if (isFunction(a1)) success = a1;
+ else if (isPostOrPut) data = a1;
+ else params = a1;
+ break;
+ case 0: break;
+ default:
+ throw "Expected between 0-4 arguments [params, data, success, error], got " +
+ arguments.length + " arguments.";
+ }
+
+ var value = this instanceof Resource ? this : (action.isArray ? [] : new Resource(data));
+ $http({
+ method: action.method,
+ url: route.url(extend({}, extractParams(data), action.params || {}, params)),
+ data: data
+ }).then(function(response) {
+ var data = response.data;
+
+ if (data) {
+ if (action.isArray) {
+ value.length = 0;
+ forEach(data, function(item) {
+ value.push(new Resource(item));
+ });
+ } else {
+ copy(data, value);
+ }
+ }
+ (success||noop)(value, response.headers);
+ }, error);
+
+ return value;
+ };
+
+
+ Resource.bind = function(additionalParamDefaults){
+ return ResourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions);
+ };
+
+
+ Resource.prototype['$' + name] = function(a1, a2, a3) {
+ var params = extractParams(this),
+ success = noop,
+ error;
+
+ switch(arguments.length) {
+ case 3: params = a1; success = a2; error = a3; break;
+ case 2:
+ case 1:
+ if (isFunction(a1)) {
+ success = a1;
+ error = a2;
+ } else {
+ params = a1;
+ success = a2 || noop;
+ }
+ case 0: break;
+ default:
+ throw "Expected between 1-3 arguments [params, success, error], got " +
+ arguments.length + " arguments.";
+ }
+ var data = isPostOrPut ? this : undefined;
+ Resource[name].call(this, params, data, success, error);
+ };
+ });
+ return Resource;
+ }
+
+ return ResourceFactory;
}];
}