diff options
| author | Rob Spies | 2010-06-22 17:09:55 -0700 | 
|---|---|---|
| committer | Rob Spies | 2010-06-22 17:09:55 -0700 | 
| commit | 1500e91defa4020bfe9608749b25e585cd1d8e3d (patch) | |
| tree | 8c2872252b62567dc4eb00f7d7547661d5674c55 /src/Resource.js | |
| parent | eaa397c76b7d28343cde9f3a0338b9b0e79197c8 (diff) | |
| parent | b129a1094e6b42ed82c3ccecc2f40daaa0a6cb6a (diff) | |
| download | angular.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.js | 140 | 
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; +  } +}; | 
