diff options
| -rw-r--r-- | src/ngResource/resource.js | 30 | ||||
| -rw-r--r-- | test/ngResource/resourceSpec.js | 62 | 
2 files changed, 79 insertions, 13 deletions
diff --git a/src/ngResource/resource.js b/src/ngResource/resource.js index ca92e629..37cc3e4d 100644 --- a/src/ngResource/resource.js +++ b/src/ngResource/resource.js @@ -53,6 +53,8 @@   *   - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of the   *     parameter value is a function, it will be executed every time when a param value needs to be   *     obtained for a request (unless the param was overriden). + *   - **`url`** – {string} – action specific `url` override. The url templating is supported just like + *     for the resource-level urls.   *   - **`isArray`** – {boolean=} – If true then the returned object for this action is an array, see   *     `returns` section.   *   - **`transformRequest`** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` – @@ -306,30 +308,32 @@ angular.module('ngResource', ['ng']).      function Route(template, defaults) {        this.template = template = template + '#';        this.defaults = defaults || {}; -      var urlParams = this.urlParams = {}; -      forEach(template.split(/\W/), function(param){ -        if (param && (new RegExp("(^|[^\\\\]):" + param + "\\W").test(template))) { -          urlParams[param] = true; -        } -      }); -      this.template = template.replace(/\\:/g, ':'); +      this.urlParams = {};      }      Route.prototype = { -      setUrlParams: function(config, params) { +      setUrlParams: function(config, params, actionUrl) {          var self = this, -            url = this.template, +            url = actionUrl || self.template,              val,              encodedVal; +        var urlParams = self.urlParams = {}; +        forEach(url.split(/\W/), function(param){ +          if (param && (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) { +              urlParams[param] = true; +          } +        }); +        url = url.replace(/\\:/g, ':'); +          params = params || {}; -        forEach(this.urlParams, function(_, urlParam){ +        forEach(self.urlParams, function(_, urlParam){            val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];            if (angular.isDefined(val) && val !== null) {              encodedVal = encodeUriSegment(val); -            url = url.replace(new RegExp(":" + urlParam + "(\\W)", "g"), encodedVal + "$1"); +            url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), encodedVal + "$1");            } else { -            url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W)", "g"), function(match, +            url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match,                  leadingSlashes, tail) {                if (tail.charAt(0) == '/') {                  return tail; @@ -427,7 +431,7 @@ angular.module('ngResource', ['ng']).              }            });            httpConfig.data = data; -          route.setUrlParams(httpConfig, extend({}, extractParams(data, action.params || {}), params)); +          route.setUrlParams(httpConfig, extend({}, extractParams(data, action.params || {}), params), action.url);            function markResolved() { value.$resolved = true; } diff --git a/test/ngResource/resourceSpec.js b/test/ngResource/resourceSpec.js index e5366f4f..11124739 100644 --- a/test/ngResource/resourceSpec.js +++ b/test/ngResource/resourceSpec.js @@ -703,4 +703,66 @@ describe("resource", function() {      $httpBackend.flush();      expect(person.id).toEqual(456);    }); + + +  describe('action-level url override', function() { + +    it('should support overriding url template with static url', function() { +      $httpBackend.expect('GET', '/override-url?type=Customer&typeId=123').respond({id: 'abc'}); +      var TypeItem = $resource('/:type/:typeId', {type: 'Order'}, { +          get: { +            method: 'GET', +            params: {type: 'Customer'}, +            url: '/override-url' +          } +      }); +      var item = TypeItem.get({typeId: 123}); +      $httpBackend.flush(); +      expect(item).toEqualData({id: 'abc'}); +    }); + + +    it('should support overriding url template with a new template ending in param', function() { +      //    url parameter in action, parameter ending the string +      $httpBackend.expect('GET', '/Customer/123').respond({id: 'abc'}); +      var TypeItem = $resource('/foo/:type', {type: 'Order'}, { +        get: { +          method: 'GET', +          params: {type: 'Customer'}, +          url: '/:type/:typeId' +        } +      }); +      var item = TypeItem.get({typeId: 123}); +      $httpBackend.flush(); +      expect(item).toEqualData({id: 'abc'}); + +      //    url parameter in action, parameter not ending the string +      $httpBackend.expect('GET', '/Customer/123/pay').respond({id: 'abc'}); +      var TypeItem = $resource('/foo/:type', {type: 'Order'}, { +        get: { +          method: 'GET', +          params: {type: 'Customer'}, +          url: '/:type/:typeId/pay' +        } +      }); +      var item = TypeItem.get({typeId: 123}); +      $httpBackend.flush(); +      expect(item).toEqualData({id: 'abc'}); +    }); + + +    it('should support overriding url template with a new template ending in string', function() { +      $httpBackend.expect('GET', '/Customer/123/pay').respond({id: 'abc'}); +      var TypeItem = $resource('/foo/:type', {type: 'Order'}, { +        get: { +          method: 'GET', +          params: {type: 'Customer'}, +          url: '/:type/:typeId/pay' +        } +      }); +      var item = TypeItem.get({typeId: 123}); +      $httpBackend.flush(); +      expect(item).toEqualData({id: 'abc'}); +    }); +  });  });  | 
