aboutsummaryrefslogtreecommitdiffstats
path: root/src/Resource.js
diff options
context:
space:
mode:
authorRob Spies2010-06-22 17:09:55 -0700
committerRob Spies2010-06-22 17:09:55 -0700
commit1500e91defa4020bfe9608749b25e585cd1d8e3d (patch)
tree8c2872252b62567dc4eb00f7d7547661d5674c55 /src/Resource.js
parenteaa397c76b7d28343cde9f3a0338b9b0e79197c8 (diff)
parentb129a1094e6b42ed82c3ccecc2f40daaa0a6cb6a (diff)
downloadangular.js-1500e91defa4020bfe9608749b25e585cd1d8e3d.tar.bz2
Merge http://github.com/angular/angular.js into angular
Conflicts: .gitignore
Diffstat (limited to 'src/Resource.js')
-rw-r--r--src/Resource.js140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/Resource.js b/src/Resource.js
new file mode 100644
index 00000000..ba460c30
--- /dev/null
+++ b/src/Resource.js
@@ -0,0 +1,140 @@
+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;
+ }
+ });
+}
+
+Route.prototype = {
+ url: function(params) {
+ var path = [];
+ var self = this;
+ var url = this.template;
+ params = params || {};
+ foreach(this.urlParams, function(_, urlParam){
+ var value = params[urlParam] || self.defaults[urlParam] || "";
+ url = url.replace(new RegExp(":" + urlParam + "(\\W)"), value + "$1");
+ });
+ url = url.replace(/\/?#$/, '');
+ var query = [];
+ foreachSorted(params, function(value, key){
+ if (!self.urlParams[key]) {
+ query.push(encodeURI(key) + '=' + encodeURI(value));
+ }
+ });
+ 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 = {
+ route: function(url, paramDefaults, actions){
+ var self = this;
+ var route = new Route(url);
+ actions = extend({}, ResourceFactory.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 isGet = action.method == 'GET';
+ var isPost = action.method == 'POST';
+ Resource[name] = function (a1, a2, a3) {
+ var params = {};
+ var data;
+ var callback = noop;
+ switch(arguments.length) {
+ case 3: callback = a3;
+ case 2:
+ if (isFunction(a2)) {
+ callback = a2;
+ } else {
+ params = a1;
+ data = a2;
+ break;
+ }
+ case 1:
+ if (isFunction(a1)) callback = a1;
+ else if (isPost) data = a1;
+ else params = a1;
+ break;
+ case 0: break;
+ default:
+ throw "Expected between 0-3 arguments [params, data, callback], got " + arguments.length + " arguments.";
+ }
+
+ var value = action.isArray ? [] : new Resource(data;)
+ self.xhr(
+ action.method,
+ route.url(extend({}, action.params || {}, extractParams(data), params)),
+ data,
+ function(status, response, clear) {
+ if (status == 200) {
+ if (action.isArray) {
+ if (action.cacheThenRetrieve)
+ value = [];
+ foreach(response, function(item){
+ value.push(new Resource(item));
+ });
+ } else {
+ copy(response, value);
+ }
+ (callback||noop)(value);
+ } else {
+ throw {status: status, response:response, message: status + ": " + response};
+ }
+ },
+ action.cacheThenRetrieve
+ );
+ return value;
+ };
+
+ Resource.bind = function(additionalParamDefaults){
+ return self.route(url, extend({}, paramDefaults, additionalParamDefaults), actions);
+ };
+
+ if (!isGet) {
+ Resource.prototype['$' + name] = function(a1, a2){
+ var params = {};
+ 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 self = this;
+ Resource[name](params, this, function(response){
+ copy(response, self);
+ callback(self);
+ });
+ };
+ }
+ });
+ return Resource;
+ }
+};