使用一个iron-ajax元素进行多个请求

时间:2016-06-15 22:16:22

标签: polymer

理论上,应该可以通过设置iron-ajax属性,然后在元素上重复设置auto属性,将一个url元素用于多个请求。 iron-ajax有一个名为activeRequests的属性,它是一个只读数组,因此它似乎支持同时排队多个请求。但实际上它似乎不起作用。

例如,在下面的JS Bin中,我检索包含单词polymer的书籍的书籍ID列表,然后使用for循环重复设置{{1}的值}}。

url

3 个答案:

答案 0 :(得分:7)

确实可以将iron-ajax用于多个请求,但不能启用auto,否则您将点击iron-ajax的{​​{3}}。来自Polymer debouncer

  

auto设置为true时,只要其urlparamsbody属性发生更改,该元素就会执行请求。在多个属性按顺序更改的情况下,自动生成的请求将被去除。

在你的问题代码中:

// template
<iron-ajax auto ...>

// script
onResponse: function(e) {
  ...
  for (var i = 0; i < ajax.lastResponse.items.length; i++) {
    ajax.url = this.url(ajax.lastResponse.items[i].id);
  }
}

...您可能希望iron-ajax为每个网址生成新请求,但docs for iron-ajax(仅采用最后一次调用)。

另外值得注意的是:response处理程序的事件详细信息(即e.detail)是对应的iron-request,其中包含AJAX响应(即e.detail.response)。使用事件详细信息是首选,因为它可以避免来自iron-ajax的同时请求中的竞争条件,其中this.$.ajax.lastResponsethis.$.ajax.lastRequest被异步覆盖。

onResponse: function(e) {
  var request = e.detail;
  var response = request.response;
}

要重新使用iron-ajax新网址,请停用auto(禁用辩护人)并在更新网址后手动调用generateRequest()。这将允许多个同时异步请求(并且activeRequests将填充多个请求)。

// template
<iron-ajax ...>   <!-- no 'auto' -->

// script
onResponse: function(e) {
  var request = e.detail;
  var response = request.response;
  ...
  for (var i = 0; i < response.items.length; i++) {
    ajax.url = this.url(response.items[i].id);
    ajax.generateRequest();
  }
},
ready: function() {
  this.$.ajax.generateRequest(); // first request
}

以下是您的代码的修改版本:

<head>
  <base href="https://polygit.org/polymer+1.5.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="polymer/polymer.html">
  <link rel="import" href="iron-ajax/iron-ajax.html">
</head>
<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
      <!-- We're reusing this iron-ajax to fetch more data
         based on the first response, and we don't want
         iron-ajax's debouncer to limit our requests,
         so disable 'auto' (i.e., remove the attribute
         from <iron-ajax>). We'll call generateRequest()
         manually instead.
      -->
    <iron-ajax id="ajax"
               url="https://www.googleapis.com/books/v1/volumes?q=polymer"
               handle-as="json"
               on-response="onResponse"
               on-error="onError">
      </iron-ajax>
    </template>
    <script>
      HTMLImports.whenReady(function() {
        Polymer({
          is: 'x-foo',
          onError: function(e) {
            console.warn('iron-ajax error:', e.detail.error.message, 'url:', e.detail.request.url);
          },
          onResponse: function(e) {
            var ajax = this.$.ajax;
            var originalUrl = 'https://www.googleapis.com/books/v1/volumes?q=polymer';
            var url = e.detail.url;
            if (url.includes(originalUrl)) {
              var books = e.detail.response.items || [];
              console.log('this is the first request');
              for (var i = 0; i < books.length && i < 3; i++) {
                ajax.url = this.url(books[i].id);
                console.log('fetching:', ajax.url);
                ajax.generateRequest();
              }
            } else {
              var book = e.detail.response;
              console.log('received:', e.detail.url, '"' + book.volumeInfo.title + '"');
            }
          },
          url: function(id) {
            return "https://www.googleapis.com/books/v1/volumes/" + id;
          },
          ready: function() {
            // generate first request
            this.$.ajax.generateRequest();
          }
        });
      });
    </script>
  </dom-module>
</body>

debouncer collapses the requests into one

答案 1 :(得分:0)

我不知道<!doctype html> <html> <head> <meta name="description" content="single iron-ajax for multiple requests"> <meta charset="utf-8"> <base href="https://polygit.org/components/"> <script href="webcomponentsjs/webcomponents-lite.min.js"></script> <link href="polymer/polymer.html" rel="import"> <link href="iron-ajax/iron-ajax.html" rel="import"> </head> <body> <dom-module id="my-el"> <template> <iron-ajax id="ajax" url="https://www.googleapis.com/books/v1/volumes?q=polymer" handle-as="json" on-response="onResponse" last-response="{{response}}" auto></iron-ajax> </template> <script> Polymer({ is: 'my-el', properties: { response: { type: Object, notify: true } }, onResponse: function(e) { var ajax = this.$.ajax; var originalUrl = 'https://www.googleapis.com/books/v1/volumes?q=polymer'; var url = ajax.lastRequest.xhr.responseURL; if (url.includes(originalUrl)) { console.log('this is the first request'); for (var i = 0; i < ajax.lastResponse.items.length; i++) { ajax.url = this.url(ajax.lastResponse.items[i].id); } } else { console.log(ajax.lastResponse.selfLink); } }, url: function(id) { return "https://www.googleapis.com/books/v1/volumes/" + id; } }); </script> </dom-module> <my-el></my-el> </body> </html> 属性是什么,但我能够通过重新构建我的代码来使其工作。基本上,只需实现一个队列,然后从队列中弹出一个项目,并在最后一个请求完成后设置activeRequests

url

https://jsbin.com/beyawe/edit?html,console

答案 2 :(得分:-1)

您可以尝试iron-multiple-ajax-behavior。 如果这对您有用,请告诉我。