angular.js/src/Resource.js

138 lines
4.1 KiB
JavaScript
Raw Normal View History

2010-03-15 21:36:50 +00:00
function Route(template, defaults) {
this.template = template = template + '#';
this.defaults = defaults || {};
var urlParams = this.urlParams = {};
forEach(template.split(/\W/), function(param){
2010-03-15 21:36:50 +00:00
if (param && template.match(new RegExp(":" + param + "\\W"))) {
urlParams[param] = true;
}
});
}
Route.prototype = {
url: function(params) {
var self = this,
url = this.template,
encodedVal;
2010-03-15 21:36:50 +00:00
params = params || {};
forEach(this.urlParams, function(_, urlParam){
encodedVal = encodeUriSegment(params[urlParam] || self.defaults[urlParam] || "")
url = url.replace(new RegExp(":" + urlParam + "(\\W)"), encodedVal + "$1");
2010-03-15 21:36:50 +00:00
});
url = url.replace(/\/?#$/, '');
var query = [];
forEachSorted(params, function(value, key){
2010-03-15 21:36:50 +00:00
if (!self.urlParams[key]) {
query.push(encodeUriSegment(key) + '=' + encodeUriSegment(value));
2010-03-15 21:36:50 +00:00
}
});
2010-07-22 18:18:32 +00:00
url = url.replace(/\/*$/, '');
2010-03-15 21:36:50 +00:00
return url + (query.length ? '?' + query.join('&') : '');
}
};
function ResourceFactory(xhr) {
this.xhr = xhr;
}
ResourceFactory.DEFAULT_ACTIONS = {
'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'}
};
ResourceFactory.prototype = {
2010-03-15 22:57:12 +00:00
route: function(url, paramDefaults, actions){
2010-03-15 21:36:50 +00:00
var self = this;
var route = new Route(url);
actions = extend({}, ResourceFactory.DEFAULT_ACTIONS, actions);
2010-03-15 22:57:12 +00:00
function extractParams(data){
2010-03-15 21:36:50 +00:00
var ids = {};
forEach(paramDefaults || {}, function(value, key){
ids[key] = value.charAt && value.charAt(0) == '@' ? getter(data, value.substr(1)) : value;
2010-03-15 21:36:50 +00:00
});
return ids;
}
function Resource(value){
copy(value || {}, this);
2010-04-04 00:04:36 +00:00
}
2010-03-15 21:36:50 +00:00
forEach(actions, function(action, name){
var isPostOrPut = action.method == 'POST' || action.method == 'PUT';
2010-03-15 21:36:50 +00:00
Resource[name] = function (a1, a2, a3) {
var params = {};
var data;
var callback = noop;
switch(arguments.length) {
case 3: callback = a3;
case 2:
2010-05-07 19:09:14 +00:00
if (isFunction(a2)) {
2010-03-15 21:36:50 +00:00
callback = a2;
2011-01-12 01:48:30 +00:00
//fallthrough
2010-03-15 21:36:50 +00:00
} else {
params = a1;
data = a2;
break;
}
2010-05-07 19:09:14 +00:00
case 1:
if (isFunction(a1)) callback = a1;
else if (isPostOrPut) data = a1;
2010-05-07 19:09:14 +00:00
else params = a1;
break;
2010-03-15 21:36:50 +00:00
case 0: break;
default:
throw "Expected between 0-3 arguments [params, data, callback], got " + arguments.length + " arguments.";
2010-03-15 21:36:50 +00:00
}
var value = this instanceof Resource ? this : (action.isArray ? [] : new Resource(data));
2010-05-19 18:51:17 +00:00
self.xhr(
action.method,
route.url(extend({}, action.params || {}, extractParams(data), params)),
data,
function(status, response, clear) {
2010-05-19 18:51:17 +00:00
if (status == 200) {
if (action.isArray) {
value.length = 0;
forEach(response, function(item){
2010-05-19 18:51:17 +00:00
value.push(new Resource(item));
});
} else {
copy(response, value);
}
(callback||noop)(value);
} else {
throw {status: status, response:response, message: status + ": " + response};
}
},
2010-10-15 20:44:53 +00:00
action.verifyCache);
2010-03-15 21:36:50 +00:00
return value;
};
2010-03-15 22:57:12 +00:00
Resource.bind = function(additionalParamDefaults){
return self.route(url, extend({}, paramDefaults, additionalParamDefaults), actions);
2010-03-15 22:57:12 +00:00
};
Resource.prototype['$' + name] = function(a1, a2){
var params = extractParams(this);
var callback = noop;
switch(arguments.length) {
case 2: params = a1; callback = a2;
case 1: if (typeof a1 == $function) callback = a1; else params = a1;
case 0: break;
default:
throw "Expected between 1-2 arguments [params, callback], got " + arguments.length + " arguments.";
}
var data = isPostOrPut ? this : undefined;
Resource[name].call(this, params, data, callback);
};
2010-03-15 21:36:50 +00:00
});
return Resource;
}
};