OLD | NEW |
(Empty) | |
| 1 <!-- |
| 2 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. |
| 3 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt |
| 4 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt |
| 5 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt |
| 6 Code distributed by Google as part of the polymer project is also |
| 7 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt |
| 8 --> |
| 9 |
| 10 <link rel="import" href="../polymer/polymer.html"> |
| 11 <link rel="import" href="iron-request.html"> |
| 12 |
| 13 <!-- |
| 14 The `iron-ajax` element exposes network request functionality. |
| 15 |
| 16 <iron-ajax |
| 17 auto |
| 18 url="http://gdata.youtube.com/feeds/api/videos/" |
| 19 params='{"alt":"json", "q":"chrome"}' |
| 20 handle-as="json" |
| 21 on-response="handleResponse" |
| 22 debounce-duration="300"></iron-ajax> |
| 23 |
| 24 With `auto` set to `true`, the element performs a request whenever |
| 25 its `url`, `params` or `body` properties are changed. Automatically generated |
| 26 requests will be debounced in the case that multiple attributes are changed |
| 27 sequentially. |
| 28 |
| 29 Note: The `params` attribute must be double quoted JSON. |
| 30 |
| 31 You can trigger a request explicitly by calling `generateRequest` on the |
| 32 element. |
| 33 --> |
| 34 |
| 35 <script> |
| 36 |
| 37 Polymer({ |
| 38 |
| 39 is: 'iron-ajax', |
| 40 |
| 41 /** |
| 42 * Fired when a request is sent. |
| 43 * |
| 44 * @event request |
| 45 */ |
| 46 |
| 47 /** |
| 48 * Fired when a response is received. |
| 49 * |
| 50 * @event response |
| 51 */ |
| 52 |
| 53 /** |
| 54 * Fired when an error is received. |
| 55 * |
| 56 * @event error |
| 57 */ |
| 58 |
| 59 properties: { |
| 60 /** |
| 61 * The URL target of the request. |
| 62 */ |
| 63 url: { |
| 64 type: String, |
| 65 value: '' |
| 66 }, |
| 67 |
| 68 /** |
| 69 * An object that contains query parameters to be appended to the |
| 70 * specified `url` when generating a request. |
| 71 */ |
| 72 params: { |
| 73 type: Object, |
| 74 value: function() { |
| 75 return {}; |
| 76 } |
| 77 }, |
| 78 |
| 79 /** |
| 80 * The HTTP method to use such as 'GET', 'POST', 'PUT', or 'DELETE'. |
| 81 * Default is 'GET'. |
| 82 */ |
| 83 method: { |
| 84 type: String, |
| 85 value: 'GET' |
| 86 }, |
| 87 |
| 88 /** |
| 89 * HTTP request headers to send. |
| 90 * |
| 91 * Example: |
| 92 * |
| 93 * <iron-ajax |
| 94 * auto |
| 95 * url="http://somesite.com" |
| 96 * headers='{"X-Requested-With": "XMLHttpRequest"}' |
| 97 * handle-as="json" |
| 98 * last-response-changed="{{handleResponse}}"></iron-ajax> |
| 99 */ |
| 100 headers: { |
| 101 type: Object, |
| 102 value: function() { |
| 103 return {}; |
| 104 } |
| 105 }, |
| 106 |
| 107 /** |
| 108 * Content type to use when sending data. If the contenttype is set |
| 109 * and a `Content-Type` header is specified in the `headers` attribute, |
| 110 * the `headers` attribute value will take precedence. |
| 111 */ |
| 112 contentType: { |
| 113 type: String, |
| 114 value: 'application/x-www-form-urlencoded' |
| 115 }, |
| 116 |
| 117 /** |
| 118 * Optional raw body content to send when method === "POST". |
| 119 * |
| 120 * Example: |
| 121 * |
| 122 * <iron-ajax method="POST" auto url="http://somesite.com" |
| 123 * body='{"foo":1, "bar":2}'> |
| 124 * </iron-ajax> |
| 125 */ |
| 126 body: { |
| 127 type: String, |
| 128 value: '' |
| 129 }, |
| 130 |
| 131 /** |
| 132 * Toggle whether XHR is synchronous or asynchronous. Don't change this |
| 133 * to true unless You Know What You Are Doing™. |
| 134 */ |
| 135 sync: { |
| 136 type: Boolean, |
| 137 value: false |
| 138 }, |
| 139 |
| 140 /** |
| 141 * Specifies what data to store in the `response` property, and |
| 142 * to deliver as `event.response` in `response` events. |
| 143 * |
| 144 * One of: |
| 145 * |
| 146 * `text`: uses `XHR.responseText`. |
| 147 * |
| 148 * `xml`: uses `XHR.responseXML`. |
| 149 * |
| 150 * `json`: uses `XHR.responseText` parsed as JSON. |
| 151 * |
| 152 * `arraybuffer`: uses `XHR.response`. |
| 153 * |
| 154 * `blob`: uses `XHR.response`. |
| 155 * |
| 156 * `document`: uses `XHR.response`. |
| 157 */ |
| 158 handleAs: { |
| 159 type: String, |
| 160 value: 'json' |
| 161 }, |
| 162 |
| 163 /** |
| 164 * Set the withCredentials flag on the request. |
| 165 */ |
| 166 withCredentials: { |
| 167 type: Boolean, |
| 168 value: false |
| 169 }, |
| 170 |
| 171 /** |
| 172 * If true, automatically performs an Ajax request when either `url` or |
| 173 * `params` changes. |
| 174 */ |
| 175 auto: { |
| 176 type: Boolean, |
| 177 value: false |
| 178 }, |
| 179 |
| 180 /** |
| 181 * If true, error messages will automatically be logged to the console. |
| 182 */ |
| 183 verbose: { |
| 184 type: Boolean, |
| 185 value: false |
| 186 }, |
| 187 |
| 188 /** |
| 189 * Will be set to true if there is at least one in-flight request |
| 190 * associated with this iron-ajax element. |
| 191 */ |
| 192 loading: { |
| 193 type: Boolean, |
| 194 notify: true, |
| 195 readOnly: true |
| 196 }, |
| 197 |
| 198 /** |
| 199 * Will be set to the most recent request made by this iron-ajax element. |
| 200 */ |
| 201 lastRequest: { |
| 202 type: Object, |
| 203 notify: true, |
| 204 readOnly: true |
| 205 }, |
| 206 |
| 207 /** |
| 208 * Will be set to the most recent response received by a request |
| 209 * that originated from this iron-ajax element. The type of the response |
| 210 * is determined by the value of `handleas` at the time that the request |
| 211 * was generated. |
| 212 */ |
| 213 lastResponse: { |
| 214 type: Object, |
| 215 notify: true, |
| 216 readOnly: true |
| 217 }, |
| 218 |
| 219 /** |
| 220 * Will be set to the most recent error that resulted from a request |
| 221 * that originated from this iron-ajax element. |
| 222 */ |
| 223 lastError: { |
| 224 type: Object, |
| 225 notify: true, |
| 226 readOnly: true |
| 227 }, |
| 228 |
| 229 /** |
| 230 * An Array of all in-flight requests originating from this iron-ajax |
| 231 * element. |
| 232 */ |
| 233 activeRequests: { |
| 234 type: Array, |
| 235 notify: true, |
| 236 readOnly: true, |
| 237 value: function() { |
| 238 this._setActiveRequests([]); |
| 239 } |
| 240 }, |
| 241 |
| 242 /** |
| 243 * Length of time in milliseconds to debounce multiple requests. |
| 244 */ |
| 245 debounceDuration: { |
| 246 type: Number, |
| 247 value: 0, |
| 248 notify: true |
| 249 }, |
| 250 |
| 251 _boundHandleResponse: { |
| 252 type: Function, |
| 253 value: function() { |
| 254 return this.handleResponse.bind(this); |
| 255 } |
| 256 }, |
| 257 |
| 258 _boundDiscardRequest: { |
| 259 type: Function, |
| 260 value: function() { |
| 261 return this.discardRequest.bind(this); |
| 262 } |
| 263 } |
| 264 }, |
| 265 |
| 266 observers: [ |
| 267 'requestOptionsChanged(url, method, params, headers,' + |
| 268 'contentType, body, sync, handleAs, withCredentials, auto)' |
| 269 ], |
| 270 |
| 271 get queryString () { |
| 272 var queryParts = []; |
| 273 var param; |
| 274 var value; |
| 275 |
| 276 for (param in this.params) { |
| 277 value = this.params[param]; |
| 278 param = window.encodeURIComponent(param); |
| 279 |
| 280 if (value !== null) { |
| 281 param += '=' + window.encodeURIComponent(value); |
| 282 } |
| 283 |
| 284 queryParts.push(param); |
| 285 } |
| 286 |
| 287 return queryParts.join('&'); |
| 288 }, |
| 289 |
| 290 get requestUrl() { |
| 291 var queryString = this.queryString; |
| 292 |
| 293 if (queryString) { |
| 294 return this.url + '?' + queryString; |
| 295 } |
| 296 |
| 297 return this.url; |
| 298 }, |
| 299 |
| 300 get requestHeaders() { |
| 301 var headers = { |
| 302 'content-type': this.contentType |
| 303 }; |
| 304 var header; |
| 305 |
| 306 if (this.headers instanceof Object) { |
| 307 for (header in this.headers) { |
| 308 headers[header] = this.headers[header].toString(); |
| 309 } |
| 310 } |
| 311 |
| 312 return headers; |
| 313 }, |
| 314 |
| 315 toRequestOptions: function() { |
| 316 return { |
| 317 url: this.requestUrl, |
| 318 method: this.method, |
| 319 headers: this.requestHeaders, |
| 320 body: this.body, |
| 321 async: !this.sync, |
| 322 handleAs: this.handleAs, |
| 323 withCredentials: this.withCredentials |
| 324 }; |
| 325 }, |
| 326 |
| 327 requestOptionsChanged: function() { |
| 328 this.debounce('generate-request', function() { |
| 329 if (!this.url && this.url !== '') { |
| 330 return; |
| 331 } |
| 332 |
| 333 if (this.auto) { |
| 334 this.generateRequest(); |
| 335 } |
| 336 }, this.debounceDuration); |
| 337 }, |
| 338 |
| 339 /** |
| 340 * Performs an AJAX request to the specified URL. |
| 341 * |
| 342 * @method generateRequest |
| 343 */ |
| 344 generateRequest: function() { |
| 345 var request = document.createElement('iron-request'); |
| 346 var requestOptions = this.toRequestOptions(); |
| 347 |
| 348 this.activeRequests.push(request); |
| 349 |
| 350 request.completes.then( |
| 351 this._boundHandleResponse |
| 352 ).catch( |
| 353 this.handleError.bind(this, request) |
| 354 ).then( |
| 355 this._boundDiscardRequest |
| 356 ); |
| 357 |
| 358 request.send(requestOptions); |
| 359 |
| 360 this._setLastRequest(request); |
| 361 |
| 362 this.fire('request', { |
| 363 request: request, |
| 364 options: requestOptions |
| 365 }); |
| 366 |
| 367 return request; |
| 368 }, |
| 369 |
| 370 handleResponse: function(request) { |
| 371 this._setLastResponse(request.response); |
| 372 this.fire('response', request); |
| 373 }, |
| 374 |
| 375 handleError: function(request, error) { |
| 376 if (this.verbose) { |
| 377 console.error(error); |
| 378 } |
| 379 |
| 380 this._setLastError({ |
| 381 request: request, |
| 382 error: error |
| 383 }); |
| 384 this.fire('error', { |
| 385 request: request, |
| 386 error: error |
| 387 }); |
| 388 }, |
| 389 |
| 390 discardRequest: function(request) { |
| 391 var requestIndex = this.activeRequests.indexOf(request); |
| 392 |
| 393 if (requestIndex > 0) { |
| 394 this.activeRequests.splice(requestIndex, 1); |
| 395 } |
| 396 } |
| 397 }); |
| 398 </script> |
OLD | NEW |