angularjs-rails 1.5.8 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -1
- data/lib/angularjs-rails/engine.rb +1 -1
- data/lib/angularjs-rails/version.rb +1 -1
- data/vendor/assets/javascripts/angular-animate.js +426 -293
- data/vendor/assets/javascripts/angular-aria.js +64 -43
- data/vendor/assets/javascripts/angular-cookies.js +24 -93
- data/vendor/assets/javascripts/angular-loader.js +190 -36
- data/vendor/assets/javascripts/angular-message-format.js +72 -84
- data/vendor/assets/javascripts/angular-messages.js +158 -68
- data/vendor/assets/javascripts/angular-mocks.js +1033 -402
- data/vendor/assets/javascripts/angular-parse-ext.js +14 -10
- data/vendor/assets/javascripts/angular-resource.js +317 -269
- data/vendor/assets/javascripts/angular-route.js +329 -132
- data/vendor/assets/javascripts/angular-sanitize.js +268 -93
- data/vendor/assets/javascripts/angular-touch.js +46 -413
- data/vendor/assets/javascripts/angular.js +9213 -4485
- metadata +2 -3
- data/vendor/assets/javascripts/angular-scenario.js +0 -44134
@@ -1,6 +1,6 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
3
|
-
* (c) 2010-
|
2
|
+
* @license AngularJS v1.8.0
|
3
|
+
* (c) 2010-2020 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
6
6
|
(function(window, angular) {'use strict';
|
@@ -1223,24 +1223,27 @@ function IDC_Y(cp) {
|
|
1223
1223
|
return false;
|
1224
1224
|
}
|
1225
1225
|
|
1226
|
+
/* eslint-disable new-cap */
|
1227
|
+
|
1226
1228
|
/**
|
1227
1229
|
* @ngdoc module
|
1228
1230
|
* @name ngParseExt
|
1229
1231
|
* @packageName angular-parse-ext
|
1230
|
-
* @description
|
1231
1232
|
*
|
1232
|
-
*
|
1233
|
+
* @description
|
1233
1234
|
*
|
1234
1235
|
* The `ngParseExt` module provides functionality to allow Unicode characters in
|
1235
|
-
* identifiers inside
|
1236
|
-
*
|
1237
|
-
*
|
1238
|
-
* <div doc-module-components="ngParseExt"></div>
|
1236
|
+
* identifiers inside AngularJS expressions.
|
1239
1237
|
*
|
1240
1238
|
* This module allows the usage of any identifier that follows ES6 identifier naming convention
|
1241
|
-
* to be used as an identifier in an
|
1239
|
+
* to be used as an identifier in an AngularJS expression. ES6 delegates some of the identifier
|
1242
1240
|
* rules definition to Unicode, this module uses ES6 and Unicode 8.0 identifiers convention.
|
1243
1241
|
*
|
1242
|
+
* <div class="alert alert-warning">
|
1243
|
+
* You cannot use Unicode characters for variable names in the {@link ngRepeat} or {@link ngOptions}
|
1244
|
+
* expressions (e.g. `ng-repeat="f in поля"`), because even with `ngParseExt` included, these
|
1245
|
+
* special expressions are not parsed by the {@link $parse} service.
|
1246
|
+
* </div>
|
1244
1247
|
*/
|
1245
1248
|
|
1246
1249
|
/* global angularParseExtModule: true,
|
@@ -1265,7 +1268,8 @@ function isValidIdentifierContinue(ch, cp) {
|
|
1265
1268
|
angular.module('ngParseExt', [])
|
1266
1269
|
.config(['$parseProvider', function($parseProvider) {
|
1267
1270
|
$parseProvider.setIdentifierFns(isValidIdentifierStart, isValidIdentifierContinue);
|
1268
|
-
}])
|
1271
|
+
}])
|
1272
|
+
.info({ angularVersion: '1.8.0' });
|
1269
1273
|
|
1270
1274
|
|
1271
1275
|
})(window, window.angular);
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
3
|
-
* (c) 2010-
|
2
|
+
* @license AngularJS v1.8.0
|
3
|
+
* (c) 2010-2020 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
6
6
|
(function(window, angular) {'use strict';
|
@@ -53,14 +53,9 @@ function shallowClearAndCopy(src, dst) {
|
|
53
53
|
* @name ngResource
|
54
54
|
* @description
|
55
55
|
*
|
56
|
-
* # ngResource
|
57
|
-
*
|
58
56
|
* The `ngResource` module provides interaction support with RESTful services
|
59
57
|
* via the $resource service.
|
60
58
|
*
|
61
|
-
*
|
62
|
-
* <div doc-module-components="ngResource"></div>
|
63
|
-
*
|
64
59
|
* See {@link ngResource.$resourceProvider} and {@link ngResource.$resource} for usage.
|
65
60
|
*/
|
66
61
|
|
@@ -120,30 +115,35 @@ function shallowClearAndCopy(src, dst) {
|
|
120
115
|
*
|
121
116
|
* @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
|
122
117
|
* `actions` methods. If a parameter value is a function, it will be called every time
|
123
|
-
* a param value needs to be obtained for a request (unless the param was overridden). The
|
124
|
-
* will be passed the current data value as an argument.
|
118
|
+
* a param value needs to be obtained for a request (unless the param was overridden). The
|
119
|
+
* function will be passed the current data value as an argument.
|
125
120
|
*
|
126
121
|
* Each key value in the parameter object is first bound to url template if present and then any
|
127
122
|
* excess keys are appended to the url search query after the `?`.
|
128
123
|
*
|
129
|
-
* Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in
|
124
|
+
* Given a template `/path/:verb` and parameter `{verb: 'greet', salutation: 'Hello'}` results in
|
130
125
|
* URL `/path/greet?salutation=Hello`.
|
131
126
|
*
|
132
127
|
* If the parameter value is prefixed with `@`, then the value for that parameter will be
|
133
|
-
* extracted from the corresponding property on the `data` object (provided when calling
|
134
|
-
*
|
128
|
+
* extracted from the corresponding property on the `data` object (provided when calling actions
|
129
|
+
* with a request body).
|
135
130
|
* For example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of
|
136
131
|
* `someParam` will be `data.someProp`.
|
137
132
|
* Note that the parameter will be ignored, when calling a "GET" action method (i.e. an action
|
138
|
-
* method that does not accept a request body)
|
133
|
+
* method that does not accept a request body).
|
134
|
+
*
|
135
|
+
* @param {Object.<Object>=} actions Hash with declaration of custom actions that will be available
|
136
|
+
* in addition to the default set of resource actions (see below). If a custom action has the same
|
137
|
+
* key as a default action (e.g. `save`), then the default action will be *overwritten*, and not
|
138
|
+
* extended.
|
139
139
|
*
|
140
|
-
*
|
141
|
-
* the default set of resource actions. The declaration should be created in the format of {@link
|
142
|
-
* ng.$http#usage $http.config}:
|
140
|
+
* The declaration should be created in the format of {@link ng.$http#usage $http.config}:
|
143
141
|
*
|
144
|
-
* {
|
145
|
-
*
|
146
|
-
*
|
142
|
+
* {
|
143
|
+
* action1: {method:?, params:?, isArray:?, headers:?, ...},
|
144
|
+
* action2: {method:?, params:?, isArray:?, headers:?, ...},
|
145
|
+
* ...
|
146
|
+
* }
|
147
147
|
*
|
148
148
|
* Where:
|
149
149
|
*
|
@@ -155,46 +155,58 @@ function shallowClearAndCopy(src, dst) {
|
|
155
155
|
* the parameter value is a function, it will be called every time when a param value needs to
|
156
156
|
* be obtained for a request (unless the param was overridden). The function will be passed the
|
157
157
|
* current data value as an argument.
|
158
|
-
* - **`url`** – {string} –
|
158
|
+
* - **`url`** – {string} – Action specific `url` override. The url templating is supported just
|
159
159
|
* like for the resource-level urls.
|
160
160
|
* - **`isArray`** – {boolean=} – If true then the returned object for this action is an array,
|
161
161
|
* see `returns` section.
|
162
162
|
* - **`transformRequest`** –
|
163
163
|
* `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
164
|
-
*
|
164
|
+
* Transform function or an array of such functions. The transform function takes the http
|
165
165
|
* request body and headers and returns its transformed (typically serialized) version.
|
166
166
|
* By default, transformRequest will contain one function that checks if the request data is
|
167
|
-
* an object and serializes
|
167
|
+
* an object and serializes it using `angular.toJson`. To prevent this behavior, set
|
168
168
|
* `transformRequest` to an empty array: `transformRequest: []`
|
169
169
|
* - **`transformResponse`** –
|
170
|
-
* `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
171
|
-
*
|
172
|
-
* response body and
|
170
|
+
* `{function(data, headersGetter, status)|Array.<function(data, headersGetter, status)>}` –
|
171
|
+
* Transform function or an array of such functions. The transform function takes the HTTP
|
172
|
+
* response body, headers and status and returns its transformed (typically deserialized)
|
173
|
+
* version.
|
173
174
|
* By default, transformResponse will contain one function that checks if the response looks
|
174
175
|
* like a JSON string and deserializes it using `angular.fromJson`. To prevent this behavior,
|
175
176
|
* set `transformResponse` to an empty array: `transformResponse: []`
|
176
|
-
* - **`cache`** – `{boolean|Cache}` –
|
177
|
-
*
|
178
|
-
* {@link
|
179
|
-
*
|
180
|
-
* - **`timeout`** – `{number}` – timeout in milliseconds.<br />
|
177
|
+
* - **`cache`** – `{boolean|Cache}` – A boolean value or object created with
|
178
|
+
* {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of the HTTP response.
|
179
|
+
* See {@link $http#caching $http Caching} for more information.
|
180
|
+
* - **`timeout`** – `{number}` – Timeout in milliseconds.<br />
|
181
181
|
* **Note:** In contrast to {@link ng.$http#usage $http.config}, {@link ng.$q promises} are
|
182
|
-
* **not** supported in
|
182
|
+
* **not** supported in `$resource`, because the same value would be used for multiple requests.
|
183
183
|
* If you are looking for a way to cancel requests, you should use the `cancellable` option.
|
184
|
-
* - **`cancellable`** – `{boolean}` –
|
185
|
-
*
|
186
|
-
*
|
187
|
-
*
|
188
|
-
* - **`withCredentials`**
|
184
|
+
* - **`cancellable`** – `{boolean}` – If true, the request made by a "non-instance" call will be
|
185
|
+
* cancelled (if not already completed) by calling `$cancelRequest()` on the call's return
|
186
|
+
* value. Calling `$cancelRequest()` for a non-cancellable or an already completed/cancelled
|
187
|
+
* request will have no effect.
|
188
|
+
* - **`withCredentials`** – `{boolean}` – Whether to set the `withCredentials` flag on the
|
189
189
|
* XHR object. See
|
190
|
-
* [
|
190
|
+
* [XMLHttpRequest.withCredentials](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials)
|
191
191
|
* for more information.
|
192
|
-
* - **`responseType`**
|
193
|
-
* [
|
194
|
-
* - **`interceptor`**
|
195
|
-
* `
|
196
|
-
*
|
197
|
-
*
|
192
|
+
* - **`responseType`** – `{string}` – See
|
193
|
+
* [XMLHttpRequest.responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType).
|
194
|
+
* - **`interceptor`** – `{Object=}` – The interceptor object has four optional methods -
|
195
|
+
* `request`, `requestError`, `response`, and `responseError`. See
|
196
|
+
* {@link ng.$http#interceptors $http interceptors} for details. Note that
|
197
|
+
* `request`/`requestError` interceptors are applied before calling `$http`, thus before any
|
198
|
+
* global `$http` interceptors. Also, rejecting or throwing an error inside the `request`
|
199
|
+
* interceptor will result in calling the `responseError` interceptor.
|
200
|
+
* The resource instance or collection is available on the `resource` property of the
|
201
|
+
* `http response` object passed to `response`/`responseError` interceptors.
|
202
|
+
* Keep in mind that the associated promise will be resolved with the value returned by the
|
203
|
+
* response interceptors. Make sure you return an appropriate value and not the `response`
|
204
|
+
* object passed as input. For reference, the default `response` interceptor (which gets applied
|
205
|
+
* if you don't specify a custom one) returns `response.resource`.<br />
|
206
|
+
* See {@link ngResource.$resource#using-interceptors below} for an example of using
|
207
|
+
* interceptors in `$resource`.
|
208
|
+
* - **`hasBody`** – `{boolean}` – If true, then the request will have a body.
|
209
|
+
* If not specified, then only POST, PUT and PATCH requests will have a body. *
|
198
210
|
* @param {Object} options Hash with custom settings that should extend the
|
199
211
|
* default `$resourceProvider` behavior. The supported options are:
|
200
212
|
*
|
@@ -207,27 +219,29 @@ function shallowClearAndCopy(src, dst) {
|
|
207
219
|
* @returns {Object} A resource "class" object with methods for the default set of resource actions
|
208
220
|
* optionally extended with custom `actions`. The default set contains these actions:
|
209
221
|
* ```js
|
210
|
-
* {
|
211
|
-
* '
|
212
|
-
* '
|
213
|
-
* '
|
214
|
-
* '
|
222
|
+
* {
|
223
|
+
* 'get': {method: 'GET'},
|
224
|
+
* 'save': {method: 'POST'},
|
225
|
+
* 'query': {method: 'GET', isArray: true},
|
226
|
+
* 'remove': {method: 'DELETE'},
|
227
|
+
* 'delete': {method: 'DELETE'}
|
228
|
+
* }
|
215
229
|
* ```
|
216
230
|
*
|
217
|
-
* Calling these methods invoke
|
218
|
-
*
|
219
|
-
*
|
220
|
-
*
|
221
|
-
*
|
231
|
+
* Calling these methods invoke {@link ng.$http} with the specified http method, destination and
|
232
|
+
* parameters. When the data is returned from the server then the object is an instance of the
|
233
|
+
* resource class. The actions `save`, `remove` and `delete` are available on it as methods with
|
234
|
+
* the `$` prefix. This allows you to easily perform CRUD operations (create, read, update,
|
235
|
+
* delete) on server-side data like this:
|
222
236
|
* ```js
|
223
|
-
* var User = $resource('/user/:userId', {userId:'@id'});
|
224
|
-
*
|
237
|
+
* var User = $resource('/user/:userId', {userId: '@id'});
|
238
|
+
* User.get({userId: 123}).$promise.then(function(user) {
|
225
239
|
* user.abc = true;
|
226
240
|
* user.$save();
|
227
241
|
* });
|
228
242
|
* ```
|
229
243
|
*
|
230
|
-
* It is important to realize that invoking a
|
244
|
+
* It is important to realize that invoking a `$resource` object method immediately returns an
|
231
245
|
* empty reference (object or array depending on `isArray`). Once the data is returned from the
|
232
246
|
* server the existing reference is populated with the actual data. This is a useful trick since
|
233
247
|
* usually the resource is assigned to a model which is then rendered by the view. Having an empty
|
@@ -238,37 +252,43 @@ function shallowClearAndCopy(src, dst) {
|
|
238
252
|
* The action methods on the class object or instance object can be invoked with the following
|
239
253
|
* parameters:
|
240
254
|
*
|
241
|
-
* -
|
242
|
-
* -
|
243
|
-
* -
|
255
|
+
* - "class" actions without a body: `Resource.action([parameters], [success], [error])`
|
256
|
+
* - "class" actions with a body: `Resource.action([parameters], postData, [success], [error])`
|
257
|
+
* - instance actions: `instance.$action([parameters], [success], [error])`
|
258
|
+
*
|
259
|
+
*
|
260
|
+
* When calling instance methods, the instance itself is used as the request body (if the action
|
261
|
+
* should have a body). By default, only actions using `POST`, `PUT` or `PATCH` have request
|
262
|
+
* bodies, but you can use the `hasBody` configuration option to specify whether an action
|
263
|
+
* should have a body or not (regardless of its HTTP method).
|
244
264
|
*
|
245
265
|
*
|
246
|
-
* Success callback is called with (value, responseHeaders)
|
247
|
-
*
|
248
|
-
* with (httpResponse) argument.
|
266
|
+
* Success callback is called with (value (Object|Array), responseHeaders (Function),
|
267
|
+
* status (number), statusText (string)) arguments, where `value` is the populated resource
|
268
|
+
* instance or collection object. The error callback is called with (httpResponse) argument.
|
249
269
|
*
|
250
|
-
* Class actions return empty instance (with additional properties below).
|
251
|
-
* Instance actions return promise
|
270
|
+
* Class actions return an empty instance (with the additional properties listed below).
|
271
|
+
* Instance actions return a promise for the operation.
|
252
272
|
*
|
253
273
|
* The Resource instances and collections have these additional properties:
|
254
274
|
*
|
255
|
-
* - `$promise`:
|
275
|
+
* - `$promise`: The {@link ng.$q promise} of the original server interaction that created this
|
256
276
|
* instance or collection.
|
257
277
|
*
|
258
278
|
* On success, the promise is resolved with the same resource instance or collection object,
|
259
|
-
* updated with data from server. This makes it easy to use in
|
260
|
-
* {@link ngRoute.$routeProvider resolve section of
|
279
|
+
* updated with data from server. This makes it easy to use in the
|
280
|
+
* {@link ngRoute.$routeProvider `resolve` section of `$routeProvider.when()`} to defer view
|
261
281
|
* rendering until the resource(s) are loaded.
|
262
282
|
*
|
263
|
-
* On failure, the promise is rejected with the {@link ng.$http http response} object
|
264
|
-
* the `resource` property.
|
283
|
+
* On failure, the promise is rejected with the {@link ng.$http http response} object.
|
265
284
|
*
|
266
285
|
* If an interceptor object was provided, the promise will instead be resolved with the value
|
267
|
-
* returned by the interceptor.
|
286
|
+
* returned by the response interceptor (on success) or responceError interceptor (on failure).
|
268
287
|
*
|
269
288
|
* - `$resolved`: `true` after first server interaction is completed (either with success or
|
270
289
|
* rejection), `false` before that. Knowing if the Resource has been resolved is useful in
|
271
|
-
* data-binding.
|
290
|
+
* data-binding. If there is a response/responseError interceptor and it returns a promise,
|
291
|
+
* `$resolved` will wait for that too.
|
272
292
|
*
|
273
293
|
* The Resource instances and collections have these additional methods:
|
274
294
|
*
|
@@ -279,138 +299,145 @@ function shallowClearAndCopy(src, dst) {
|
|
279
299
|
*
|
280
300
|
* - `toJSON`: It returns a simple object without any of the extra properties added as part of
|
281
301
|
* the Resource API. This object can be serialized through {@link angular.toJson} safely
|
282
|
-
* without attaching
|
302
|
+
* without attaching AngularJS-specific fields. Notice that `JSON.stringify` (and
|
283
303
|
* `angular.toJson`) automatically use this method when serializing a Resource instance
|
284
|
-
* (see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON
|
304
|
+
* (see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON%28%29_behavior)).
|
285
305
|
*
|
286
306
|
* @example
|
287
307
|
*
|
288
|
-
*
|
308
|
+
* ### Basic usage
|
289
309
|
*
|
290
|
-
|
291
|
-
// Define CreditCard class
|
292
|
-
var CreditCard = $resource('/
|
293
|
-
|
294
|
-
|
295
|
-
|
310
|
+
```js
|
311
|
+
// Define a CreditCard class
|
312
|
+
var CreditCard = $resource('/users/:userId/cards/:cardId',
|
313
|
+
{userId: 123, cardId: '@id'}, {
|
314
|
+
charge: {method: 'POST', params: {charge: true}}
|
315
|
+
});
|
296
316
|
|
297
317
|
// We can retrieve a collection from the server
|
298
|
-
var cards = CreditCard.query(
|
299
|
-
|
300
|
-
|
318
|
+
var cards = CreditCard.query();
|
319
|
+
// GET: /users/123/cards
|
320
|
+
// server returns: [{id: 456, number: '1234', name: 'Smith'}]
|
301
321
|
|
322
|
+
// Wait for the request to complete
|
323
|
+
cards.$promise.then(function() {
|
302
324
|
var card = cards[0];
|
303
|
-
|
325
|
+
|
326
|
+
// Each item is an instance of CreditCard
|
304
327
|
expect(card instanceof CreditCard).toEqual(true);
|
305
|
-
|
306
|
-
//
|
328
|
+
|
329
|
+
// Non-GET methods are mapped onto the instances
|
330
|
+
card.name = 'J. Smith';
|
307
331
|
card.$save();
|
308
|
-
|
309
|
-
|
332
|
+
// POST: /users/123/cards/456 {id: 456, number: '1234', name: 'J. Smith'}
|
333
|
+
// server returns: {id: 456, number: '1234', name: 'J. Smith'}
|
310
334
|
|
311
|
-
//
|
312
|
-
card.$charge({amount:9.99});
|
313
|
-
|
335
|
+
// Our custom method is mapped as well (since it uses POST)
|
336
|
+
card.$charge({amount: 9.99});
|
337
|
+
// POST: /users/123/cards/456?amount=9.99&charge=true {id: 456, number: '1234', name: 'J. Smith'}
|
314
338
|
});
|
315
339
|
|
316
|
-
//
|
317
|
-
var newCard = new CreditCard({number:'0123'});
|
318
|
-
newCard.name =
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
340
|
+
// We can create an instance as well
|
341
|
+
var newCard = new CreditCard({number: '0123'});
|
342
|
+
newCard.name = 'Mike Smith';
|
343
|
+
|
344
|
+
var savePromise = newCard.$save();
|
345
|
+
// POST: /users/123/cards {number: '0123', name: 'Mike Smith'}
|
346
|
+
// server returns: {id: 789, number: '0123', name: 'Mike Smith'}
|
347
|
+
|
348
|
+
savePromise.then(function() {
|
349
|
+
// Once the promise is resolved, the created instance
|
350
|
+
// is populated with the data returned by the server
|
351
|
+
expect(newCard.id).toEqual(789);
|
352
|
+
});
|
353
|
+
```
|
324
354
|
*
|
325
|
-
* The object returned from
|
326
|
-
* for each action in the definition.
|
355
|
+
* The object returned from a call to `$resource` is a resource "class" which has one "static"
|
356
|
+
* method for each action in the definition.
|
327
357
|
*
|
328
|
-
* Calling these methods
|
329
|
-
* `headers`.
|
358
|
+
* Calling these methods invokes `$http` on the `url` template with the given HTTP `method`,
|
359
|
+
* `params` and `headers`.
|
330
360
|
*
|
331
361
|
* @example
|
332
362
|
*
|
333
|
-
*
|
363
|
+
* ### Accessing the response
|
334
364
|
*
|
335
365
|
* When the data is returned from the server then the object is an instance of the resource type and
|
336
366
|
* all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
|
337
367
|
* operations (create, read, update, delete) on server-side data.
|
338
|
-
|
368
|
+
*
|
339
369
|
```js
|
340
|
-
var User = $resource('/
|
341
|
-
User.get({userId:123}
|
370
|
+
var User = $resource('/users/:userId', {userId: '@id'});
|
371
|
+
User.get({userId: 123}).$promise.then(function(user) {
|
342
372
|
user.abc = true;
|
343
373
|
user.$save();
|
344
374
|
});
|
345
375
|
```
|
346
376
|
*
|
347
|
-
* It's worth noting that the success callback for `get`, `query` and other methods gets
|
348
|
-
*
|
349
|
-
*
|
377
|
+
* It's worth noting that the success callback for `get`, `query` and other methods gets called with
|
378
|
+
* the resource instance (populated with the data that came from the server) as well as an `$http`
|
379
|
+
* header getter function, the HTTP status code and the response status text. So one could rewrite
|
380
|
+
* the above example and get access to HTTP headers as follows:
|
350
381
|
*
|
351
382
|
```js
|
352
|
-
var User = $resource('/
|
353
|
-
User.get({userId:123}, function(user, getResponseHeaders){
|
383
|
+
var User = $resource('/users/:userId', {userId: '@id'});
|
384
|
+
User.get({userId: 123}, function(user, getResponseHeaders) {
|
354
385
|
user.abc = true;
|
355
386
|
user.$save(function(user, putResponseHeaders) {
|
356
|
-
//user => saved
|
357
|
-
//putResponseHeaders =>
|
387
|
+
// `user` => saved `User` object
|
388
|
+
// `putResponseHeaders` => `$http` header getter
|
358
389
|
});
|
359
390
|
});
|
360
391
|
```
|
361
392
|
*
|
362
|
-
* You can also access the raw `$http` promise via the `$promise` property on the object returned
|
363
|
-
*
|
364
|
-
```
|
365
|
-
var User = $resource('/user/:userId', {userId:'@id'});
|
366
|
-
User.get({userId:123})
|
367
|
-
.$promise.then(function(user) {
|
368
|
-
$scope.user = user;
|
369
|
-
});
|
370
|
-
```
|
371
|
-
*
|
372
393
|
* @example
|
373
394
|
*
|
374
|
-
*
|
395
|
+
* ### Creating custom actions
|
375
396
|
*
|
376
|
-
* In this example we create a custom method on our resource to make a PUT request
|
377
|
-
*
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
397
|
+
* In this example we create a custom method on our resource to make a PUT request:
|
398
|
+
*
|
399
|
+
```js
|
400
|
+
var app = angular.module('app', ['ngResource']);
|
401
|
+
|
402
|
+
// Some APIs expect a PUT request in the format URL/object/ID
|
403
|
+
// Here we are creating an 'update' method
|
404
|
+
app.factory('Notes', ['$resource', function($resource) {
|
405
|
+
return $resource('/notes/:id', {id: '@id'}, {
|
406
|
+
update: {method: 'PUT'}
|
407
|
+
});
|
408
|
+
}]);
|
409
|
+
|
410
|
+
// In our controller we get the ID from the URL using `$location`
|
411
|
+
app.controller('NotesCtrl', ['$location', 'Notes', function($location, Notes) {
|
412
|
+
// First, retrieve the corresponding `Note` object from the server
|
413
|
+
// (Assuming a URL of the form `.../notes?id=XYZ`)
|
414
|
+
var noteId = $location.search().id;
|
415
|
+
var note = Notes.get({id: noteId});
|
416
|
+
|
417
|
+
note.$promise.then(function() {
|
418
|
+
note.content = 'Hello, world!';
|
419
|
+
|
420
|
+
// Now call `update` to save the changes on the server
|
421
|
+
Notes.update(note);
|
422
|
+
// This will PUT /notes/ID with the note object as the request payload
|
423
|
+
|
424
|
+
// Since `update` is a non-GET method, it will also be available on the instance
|
425
|
+
// (prefixed with `$`), so we could replace the `Note.update()` call with:
|
426
|
+
//note.$update();
|
427
|
+
});
|
428
|
+
}]);
|
429
|
+
```
|
403
430
|
*
|
404
431
|
* @example
|
405
432
|
*
|
406
|
-
*
|
433
|
+
* ### Cancelling requests
|
407
434
|
*
|
408
435
|
* If an action's configuration specifies that it is cancellable, you can cancel the request related
|
409
436
|
* to an instance or collection (as long as it is a result of a "non-instance" call):
|
410
437
|
*
|
411
438
|
```js
|
412
439
|
// ...defining the `Hotel` resource...
|
413
|
-
var Hotel = $resource('/api/
|
440
|
+
var Hotel = $resource('/api/hotels/:id', {id: '@id'}, {
|
414
441
|
// Let's make the `query()` method cancellable
|
415
442
|
query: {method: 'get', isArray: true, cancellable: true}
|
416
443
|
});
|
@@ -420,18 +447,60 @@ function shallowClearAndCopy(src, dst) {
|
|
420
447
|
this.onDestinationChanged = function onDestinationChanged(destination) {
|
421
448
|
// We don't care about any pending request for hotels
|
422
449
|
// in a different destination any more
|
423
|
-
this.availableHotels
|
450
|
+
if (this.availableHotels) {
|
451
|
+
this.availableHotels.$cancelRequest();
|
452
|
+
}
|
424
453
|
|
425
|
-
// Let's query for hotels in
|
426
|
-
// (calls: /api/
|
454
|
+
// Let's query for hotels in `destination`
|
455
|
+
// (calls: /api/hotels?location=<destination>)
|
427
456
|
this.availableHotels = Hotel.query({location: destination});
|
428
457
|
};
|
429
458
|
```
|
430
459
|
*
|
460
|
+
* @example
|
461
|
+
*
|
462
|
+
* ### Using interceptors
|
463
|
+
*
|
464
|
+
* You can use interceptors to transform the request or response, perform additional operations, and
|
465
|
+
* modify the returned instance/collection. The following example, uses `request` and `response`
|
466
|
+
* interceptors to augment the returned instance with additional info:
|
467
|
+
*
|
468
|
+
```js
|
469
|
+
var Thing = $resource('/api/things/:id', {id: '@id'}, {
|
470
|
+
save: {
|
471
|
+
method: 'POST',
|
472
|
+
interceptor: {
|
473
|
+
request: function(config) {
|
474
|
+
// Before the request is sent out, store a timestamp on the request config
|
475
|
+
config.requestTimestamp = Date.now();
|
476
|
+
return config;
|
477
|
+
},
|
478
|
+
response: function(response) {
|
479
|
+
// Get the instance from the response object
|
480
|
+
var instance = response.resource;
|
481
|
+
|
482
|
+
// Augment the instance with a custom `saveLatency` property, computed as the time
|
483
|
+
// between sending the request and receiving the response.
|
484
|
+
instance.saveLatency = Date.now() - response.config.requestTimestamp;
|
485
|
+
|
486
|
+
// Return the instance
|
487
|
+
return instance;
|
488
|
+
}
|
489
|
+
}
|
490
|
+
}
|
491
|
+
});
|
492
|
+
|
493
|
+
Thing.save({foo: 'bar'}).$promise.then(function(thing) {
|
494
|
+
console.log('That thing was saved in ' + thing.saveLatency + 'ms.');
|
495
|
+
});
|
496
|
+
```
|
497
|
+
*
|
431
498
|
*/
|
432
499
|
angular.module('ngResource', ['ng']).
|
433
|
-
|
434
|
-
|
500
|
+
info({ angularVersion: '1.8.0' }).
|
501
|
+
provider('$resource', function ResourceProvider() {
|
502
|
+
var PROTOCOL_AND_IPV6_REGEX = /^https?:\/\/\[[^\]]*][^/]*/;
|
503
|
+
|
435
504
|
var provider = this;
|
436
505
|
|
437
506
|
/**
|
@@ -475,11 +544,11 @@ angular.module('ngResource', ['ng']).
|
|
475
544
|
* ```js
|
476
545
|
* angular.
|
477
546
|
* module('myApp').
|
478
|
-
* config(['resourceProvider', function ($resourceProvider) {
|
547
|
+
* config(['$resourceProvider', function ($resourceProvider) {
|
479
548
|
* $resourceProvider.defaults.actions.update = {
|
480
549
|
* method: 'PUT'
|
481
550
|
* };
|
482
|
-
* });
|
551
|
+
* }]);
|
483
552
|
* ```
|
484
553
|
*
|
485
554
|
* Or you can even overwrite the whole `actions` list and specify your own:
|
@@ -487,9 +556,9 @@ angular.module('ngResource', ['ng']).
|
|
487
556
|
* ```js
|
488
557
|
* angular.
|
489
558
|
* module('myApp').
|
490
|
-
* config(['resourceProvider', function ($resourceProvider) {
|
559
|
+
* config(['$resourceProvider', function ($resourceProvider) {
|
491
560
|
* $resourceProvider.defaults.actions = {
|
492
|
-
* create: {method: 'POST'}
|
561
|
+
* create: {method: 'POST'},
|
493
562
|
* get: {method: 'GET'},
|
494
563
|
* getAll: {method: 'GET', isArray:true},
|
495
564
|
* update: {method: 'PUT'},
|
@@ -519,49 +588,15 @@ angular.module('ngResource', ['ng']).
|
|
519
588
|
this.$get = ['$http', '$log', '$q', '$timeout', function($http, $log, $q, $timeout) {
|
520
589
|
|
521
590
|
var noop = angular.noop,
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
* segment = *pchar
|
532
|
-
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
533
|
-
* pct-encoded = "%" HEXDIG HEXDIG
|
534
|
-
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
535
|
-
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
536
|
-
* / "*" / "+" / "," / ";" / "="
|
537
|
-
*/
|
538
|
-
function encodeUriSegment(val) {
|
539
|
-
return encodeUriQuery(val, true).
|
540
|
-
replace(/%26/gi, '&').
|
541
|
-
replace(/%3D/gi, '=').
|
542
|
-
replace(/%2B/gi, '+');
|
543
|
-
}
|
544
|
-
|
545
|
-
|
546
|
-
/**
|
547
|
-
* This method is intended for encoding *key* or *value* parts of query component. We need a
|
548
|
-
* custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't
|
549
|
-
* have to be encoded per http://tools.ietf.org/html/rfc3986:
|
550
|
-
* query = *( pchar / "/" / "?" )
|
551
|
-
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
552
|
-
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
553
|
-
* pct-encoded = "%" HEXDIG HEXDIG
|
554
|
-
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
555
|
-
* / "*" / "+" / "," / ";" / "="
|
556
|
-
*/
|
557
|
-
function encodeUriQuery(val, pctEncodeSpaces) {
|
558
|
-
return encodeURIComponent(val).
|
559
|
-
replace(/%40/gi, '@').
|
560
|
-
replace(/%3A/gi, ':').
|
561
|
-
replace(/%24/g, '$').
|
562
|
-
replace(/%2C/gi, ',').
|
563
|
-
replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
|
564
|
-
}
|
591
|
+
forEach = angular.forEach,
|
592
|
+
extend = angular.extend,
|
593
|
+
copy = angular.copy,
|
594
|
+
isArray = angular.isArray,
|
595
|
+
isDefined = angular.isDefined,
|
596
|
+
isFunction = angular.isFunction,
|
597
|
+
isNumber = angular.isNumber,
|
598
|
+
encodeUriQuery = angular.$$encodeUriQuery,
|
599
|
+
encodeUriSegment = angular.$$encodeUriSegment;
|
565
600
|
|
566
601
|
function Route(template, defaults) {
|
567
602
|
this.template = template;
|
@@ -575,42 +610,42 @@ angular.module('ngResource', ['ng']).
|
|
575
610
|
url = actionUrl || self.template,
|
576
611
|
val,
|
577
612
|
encodedVal,
|
578
|
-
|
613
|
+
protocolAndIpv6 = '';
|
579
614
|
|
580
|
-
var urlParams = self.urlParams =
|
615
|
+
var urlParams = self.urlParams = Object.create(null);
|
581
616
|
forEach(url.split(/\W/), function(param) {
|
582
617
|
if (param === 'hasOwnProperty') {
|
583
|
-
throw $resourceMinErr('badname',
|
618
|
+
throw $resourceMinErr('badname', 'hasOwnProperty is not a valid parameter name.');
|
584
619
|
}
|
585
|
-
if (!(new RegExp(
|
586
|
-
(new RegExp(
|
620
|
+
if (!(new RegExp('^\\d+$').test(param)) && param &&
|
621
|
+
(new RegExp('(^|[^\\\\]):' + param + '(\\W|$)').test(url))) {
|
587
622
|
urlParams[param] = {
|
588
|
-
isQueryParamValue: (new RegExp(
|
623
|
+
isQueryParamValue: (new RegExp('\\?.*=:' + param + '(?:\\W|$)')).test(url)
|
589
624
|
};
|
590
625
|
}
|
591
626
|
});
|
592
627
|
url = url.replace(/\\:/g, ':');
|
593
|
-
url = url.replace(
|
594
|
-
|
628
|
+
url = url.replace(PROTOCOL_AND_IPV6_REGEX, function(match) {
|
629
|
+
protocolAndIpv6 = match;
|
595
630
|
return '';
|
596
631
|
});
|
597
632
|
|
598
633
|
params = params || {};
|
599
634
|
forEach(self.urlParams, function(paramInfo, urlParam) {
|
600
635
|
val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
|
601
|
-
if (
|
636
|
+
if (isDefined(val) && val !== null) {
|
602
637
|
if (paramInfo.isQueryParamValue) {
|
603
638
|
encodedVal = encodeUriQuery(val, true);
|
604
639
|
} else {
|
605
640
|
encodedVal = encodeUriSegment(val);
|
606
641
|
}
|
607
|
-
url = url.replace(new RegExp(
|
642
|
+
url = url.replace(new RegExp(':' + urlParam + '(\\W|$)', 'g'), function(match, p1) {
|
608
643
|
return encodedVal + p1;
|
609
644
|
});
|
610
645
|
} else {
|
611
|
-
url = url.replace(new RegExp(
|
646
|
+
url = url.replace(new RegExp('(/?):' + urlParam + '(\\W|$)', 'g'), function(match,
|
612
647
|
leadingSlashes, tail) {
|
613
|
-
if (tail.charAt(0)
|
648
|
+
if (tail.charAt(0) === '/') {
|
614
649
|
return tail;
|
615
650
|
} else {
|
616
651
|
return leadingSlashes + tail;
|
@@ -624,11 +659,12 @@ angular.module('ngResource', ['ng']).
|
|
624
659
|
url = url.replace(/\/+$/, '') || '/';
|
625
660
|
}
|
626
661
|
|
627
|
-
//
|
628
|
-
// E.g. `http://url.com/id
|
662
|
+
// Collapse `/.` if found in the last URL path segment before the query.
|
663
|
+
// E.g. `http://url.com/id/.format?q=x` becomes `http://url.com/id.format?q=x`.
|
629
664
|
url = url.replace(/\/\.(?=\w+($|\?))/, '.');
|
630
|
-
//
|
631
|
-
|
665
|
+
// Replace escaped `/\.` with `/.`.
|
666
|
+
// (If `\.` comes from a param value, it will be encoded as `%5C.`.)
|
667
|
+
config.url = protocolAndIpv6 + url.replace(/\/(\\|%5C)\./, '/.');
|
632
668
|
|
633
669
|
|
634
670
|
// set params - delegate param encoding to $http
|
@@ -652,7 +688,7 @@ angular.module('ngResource', ['ng']).
|
|
652
688
|
actionParams = extend({}, paramDefaults, actionParams);
|
653
689
|
forEach(actionParams, function(value, key) {
|
654
690
|
if (isFunction(value)) { value = value(data); }
|
655
|
-
ids[key] = value && value.charAt && value.charAt(0)
|
691
|
+
ids[key] = value && value.charAt && value.charAt(0) === '@' ?
|
656
692
|
lookupDottedPath(data, value.substr(1)) : value;
|
657
693
|
});
|
658
694
|
return ids;
|
@@ -670,17 +706,17 @@ angular.module('ngResource', ['ng']).
|
|
670
706
|
var data = extend({}, this);
|
671
707
|
delete data.$promise;
|
672
708
|
delete data.$resolved;
|
709
|
+
delete data.$cancelRequest;
|
673
710
|
return data;
|
674
711
|
};
|
675
712
|
|
676
713
|
forEach(actions, function(action, name) {
|
677
|
-
var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
|
714
|
+
var hasBody = action.hasBody === true || (action.hasBody !== false && /^(POST|PUT|PATCH)$/i.test(action.method));
|
678
715
|
var numericTimeout = action.timeout;
|
679
|
-
var cancellable =
|
680
|
-
|
681
|
-
provider.defaults.cancellable;
|
716
|
+
var cancellable = isDefined(action.cancellable) ?
|
717
|
+
action.cancellable : route.defaults.cancellable;
|
682
718
|
|
683
|
-
if (numericTimeout && !
|
719
|
+
if (numericTimeout && !isNumber(numericTimeout)) {
|
684
720
|
$log.debug('ngResource:\n' +
|
685
721
|
' Only numeric values are allowed as `timeout`.\n' +
|
686
722
|
' Promises are not supported in $resource, because the same value would ' +
|
@@ -691,54 +727,61 @@ angular.module('ngResource', ['ng']).
|
|
691
727
|
}
|
692
728
|
|
693
729
|
Resource[name] = function(a1, a2, a3, a4) {
|
694
|
-
var params = {}, data,
|
730
|
+
var params = {}, data, onSuccess, onError;
|
695
731
|
|
696
|
-
/* jshint -W086 */ /* (purposefully fall through case statements) */
|
697
732
|
switch (arguments.length) {
|
698
733
|
case 4:
|
699
|
-
|
700
|
-
|
701
|
-
|
734
|
+
onError = a4;
|
735
|
+
onSuccess = a3;
|
736
|
+
// falls through
|
702
737
|
case 3:
|
703
738
|
case 2:
|
704
739
|
if (isFunction(a2)) {
|
705
740
|
if (isFunction(a1)) {
|
706
|
-
|
707
|
-
|
741
|
+
onSuccess = a1;
|
742
|
+
onError = a2;
|
708
743
|
break;
|
709
744
|
}
|
710
745
|
|
711
|
-
|
712
|
-
|
713
|
-
//
|
746
|
+
onSuccess = a2;
|
747
|
+
onError = a3;
|
748
|
+
// falls through
|
714
749
|
} else {
|
715
750
|
params = a1;
|
716
751
|
data = a2;
|
717
|
-
|
752
|
+
onSuccess = a3;
|
718
753
|
break;
|
719
754
|
}
|
755
|
+
// falls through
|
720
756
|
case 1:
|
721
|
-
if (isFunction(a1))
|
757
|
+
if (isFunction(a1)) onSuccess = a1;
|
722
758
|
else if (hasBody) data = a1;
|
723
759
|
else params = a1;
|
724
760
|
break;
|
725
761
|
case 0: break;
|
726
762
|
default:
|
727
763
|
throw $resourceMinErr('badargs',
|
728
|
-
|
764
|
+
'Expected up to 4 arguments [params, data, success, error], got {0} arguments',
|
729
765
|
arguments.length);
|
730
766
|
}
|
731
|
-
/* jshint +W086 */ /* (purposefully fall through case statements) */
|
732
767
|
|
733
768
|
var isInstanceCall = this instanceof Resource;
|
734
769
|
var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
|
735
770
|
var httpConfig = {};
|
771
|
+
var requestInterceptor = action.interceptor && action.interceptor.request || undefined;
|
772
|
+
var requestErrorInterceptor = action.interceptor && action.interceptor.requestError ||
|
773
|
+
undefined;
|
736
774
|
var responseInterceptor = action.interceptor && action.interceptor.response ||
|
737
775
|
defaultResponseInterceptor;
|
738
776
|
var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||
|
739
|
-
|
777
|
+
$q.reject;
|
778
|
+
var successCallback = onSuccess ? function(val) {
|
779
|
+
onSuccess(val, response.headers, response.status, response.statusText);
|
780
|
+
} : undefined;
|
781
|
+
var errorCallback = onError || undefined;
|
740
782
|
var timeoutDeferred;
|
741
783
|
var numericTimeoutPromise;
|
784
|
+
var response;
|
742
785
|
|
743
786
|
forEach(action, function(value, key) {
|
744
787
|
switch (key) {
|
@@ -767,23 +810,28 @@ angular.module('ngResource', ['ng']).
|
|
767
810
|
extend({}, extractParams(data, action.params || {}), params),
|
768
811
|
action.url);
|
769
812
|
|
770
|
-
|
771
|
-
|
813
|
+
// Start the promise chain
|
814
|
+
var promise = $q.
|
815
|
+
resolve(httpConfig).
|
816
|
+
then(requestInterceptor).
|
817
|
+
catch(requestErrorInterceptor).
|
818
|
+
then($http);
|
819
|
+
|
820
|
+
promise = promise.then(function(resp) {
|
821
|
+
var data = resp.data;
|
772
822
|
|
773
823
|
if (data) {
|
774
824
|
// Need to convert action.isArray to boolean in case it is undefined
|
775
|
-
|
776
|
-
if (angular.isArray(data) !== (!!action.isArray)) {
|
825
|
+
if (isArray(data) !== (!!action.isArray)) {
|
777
826
|
throw $resourceMinErr('badcfg',
|
778
827
|
'Error in resource configuration for action `{0}`. Expected response to ' +
|
779
828
|
'contain an {1} but got an {2} (Request: {3} {4})', name, action.isArray ? 'array' : 'object',
|
780
|
-
|
829
|
+
isArray(data) ? 'array' : 'object', httpConfig.method, httpConfig.url);
|
781
830
|
}
|
782
|
-
// jshint +W018
|
783
831
|
if (action.isArray) {
|
784
832
|
value.length = 0;
|
785
833
|
forEach(data, function(item) {
|
786
|
-
if (typeof item ===
|
834
|
+
if (typeof item === 'object') {
|
787
835
|
value.push(new Resource(item));
|
788
836
|
} else {
|
789
837
|
// Valid JSON values may be string literals, and these should not be converted
|
@@ -798,30 +846,27 @@ angular.module('ngResource', ['ng']).
|
|
798
846
|
value.$promise = promise; // Restore the promise
|
799
847
|
}
|
800
848
|
}
|
801
|
-
response.resource = value;
|
802
849
|
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
850
|
+
resp.resource = value;
|
851
|
+
response = resp;
|
852
|
+
return responseInterceptor(resp);
|
853
|
+
}, function(rejectionOrResponse) {
|
854
|
+
rejectionOrResponse.resource = value;
|
855
|
+
response = rejectionOrResponse;
|
856
|
+
return responseErrorInterceptor(rejectionOrResponse);
|
807
857
|
});
|
808
858
|
|
809
|
-
promise['finally'](function() {
|
859
|
+
promise = promise['finally'](function() {
|
810
860
|
value.$resolved = true;
|
811
861
|
if (!isInstanceCall && cancellable) {
|
812
|
-
value.$cancelRequest =
|
862
|
+
value.$cancelRequest = noop;
|
813
863
|
$timeout.cancel(numericTimeoutPromise);
|
814
864
|
timeoutDeferred = numericTimeoutPromise = httpConfig.timeout = null;
|
815
865
|
}
|
816
866
|
});
|
817
867
|
|
818
|
-
|
819
|
-
|
820
|
-
var value = responseInterceptor(response);
|
821
|
-
(success || noop)(value, response.headers);
|
822
|
-
return value;
|
823
|
-
},
|
824
|
-
responseErrorInterceptor);
|
868
|
+
// Run the `success`/`error` callbacks, but do not let them affect the returned promise.
|
869
|
+
promise.then(successCallback, errorCallback);
|
825
870
|
|
826
871
|
if (!isInstanceCall) {
|
827
872
|
// we are creating instance / collection
|
@@ -829,13 +874,20 @@ angular.module('ngResource', ['ng']).
|
|
829
874
|
// - return the instance / collection
|
830
875
|
value.$promise = promise;
|
831
876
|
value.$resolved = false;
|
832
|
-
if (cancellable) value.$cancelRequest =
|
877
|
+
if (cancellable) value.$cancelRequest = cancelRequest;
|
833
878
|
|
834
879
|
return value;
|
835
880
|
}
|
836
881
|
|
837
882
|
// instance call
|
838
883
|
return promise;
|
884
|
+
|
885
|
+
function cancelRequest(value) {
|
886
|
+
promise.catch(noop);
|
887
|
+
if (timeoutDeferred !== null) {
|
888
|
+
timeoutDeferred.resolve(value);
|
889
|
+
}
|
890
|
+
}
|
839
891
|
};
|
840
892
|
|
841
893
|
|
@@ -848,10 +900,6 @@ angular.module('ngResource', ['ng']).
|
|
848
900
|
};
|
849
901
|
});
|
850
902
|
|
851
|
-
Resource.bind = function(additionalParamDefaults) {
|
852
|
-
return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions);
|
853
|
-
};
|
854
|
-
|
855
903
|
return Resource;
|
856
904
|
}
|
857
905
|
|