5

iron-ajax当请求正在进行但没有成功时,我试图显示纸质进度。下面是get-products-service托管iron-ajax请求的自定义元素的代码,以及products-list托管paper-progress.

这是整体products-list dom-module

<dom-module id="product-list">
  <style>
    :host {
      display: block;
      width: 100%;
      text-align: center;
    }
    product-card {
      margin-left: 10px;
      margin-bottom: 30px;
    }
</style>
<template>
  <template is="dom-if" if="{{loading}}">
    <paper-progress value="10" indeterminate="true"  style="width:100%;"></paper-progress>
  </template>
  <paper-button id="previous" on-tap='previousPage'>Previous</paper-button>
  <paper-button id="next" on-tap='nextPage'>Next</paper-button>

  <get-products-service products="{{products}}" id="productservice"   page="{{page}}" loading="{{loading}}"></get-products-service>
 <div>
    <template is="dom-repeat" items="{{products}}">
     <product-card on-cart-tap="handleCart" product="{{item}}">
       <img width="100" height="100">
       <h3>{{item.name}}</h3>
       <h4>{{item.display_price}}</h4>
     </product-card>
    </template>
  </div>
</template>
</dom-module>
<script>
  (function() {
  Polymer({
  is: 'product-list',

  properties: {
    page: {
      type: Number,
      notify: true,
      value: 1
    }
  },
  handleCart: function(event) {

  },
  previousPage: function(event){
   this.page = --this.page;
   console.log("page: "+this.page);
  },
  nextPage: function(event){
    this.page = ++this.page;
    console.log("page: "+this.page);
  }
});
})();
</script>

这是整个get-products-service

<dom-module id="get-products-service">
  <style>
    :host {
     display: none;
    }
  </style>
<template>
  <iron-ajax id="productsajax"
    url="http://localhost:3003/api/products"
    params='{"token":"mytoken"}'
    method='GET'
    on-response='productsLoaded'
    handleAs="json"
    loading="{{loading}}" >
  </iron-ajax>
  </template>
</dom-module>

<script>
 (function() {

   Polymer({is: 'get-products-service',

     properties: {
       products: {
       type: Array,
       notify: true
     }, 
    page: {
      type: String,
      notify: true,
    },
    perpage: {
      type: String,
      readOnly: true,
      value: "6"
    },
    loading: {
      type: Boolean,
      readOnly: true,
      notify: true,
      value: false
    }
  },

productsLoaded: function(request) {
  console.log(this.$.productsajax.lastResponse);
  responseObject = this.$.productsajax.lastResponse;
  this.products = responseObject.products;
},

ready: function(){
  this.$.productsajax.params.page = this.page;
  this.$.productsajax.params.per_page = this.perpage;
},
observers: [
          'attributesReady(page)'
        ],

attributesReady: function(page) {
    this.page = page;
    this.$.productsajax.params.page = page;
    this.$.productsajax.params.per_page = this.perpage;
    console.log("service page: "+page);
    this.async(function() {
        this.$.productsajax.generateRequest();
      }, 3000);
  }
 });
})();
</script>
4

5 回答 5

7

您最好的选择是将您的担忧分开。首先,您的get-products-service

<dom-module id="get-products-service">
  <style>
    :host {
      display: none;
    }
  </style>
  <template>
    <iron-ajax id="productsajax"
      url="http://localhost:3003/api/products"
      method='GET'
      loading="{{loading}}"
      handleAs="json">
    </iron-ajax>
  </template>

  <script>
    Polymer({
      is: 'get-products-service',

      properties: {
        loading: {
          type: Boolean,
          readOnly: true,
          notify: true,
          value: false
        }
      }
    });
  </script>
</dom-module>

然后,在你的product-list

<template>
  <template is="dom-if" if="{{loading}}">
    <paper-progress value="10" indeterminate="true" style="width:100%;"></paper-progress>
  </template>
  <get-products-service loading="{{loading}}"></get-products-service>
</template>

这样get-products-servicepaper-progress就不必彼此了解任何信息,并且应该在您的应用程序的其他地方更具可组合性。

于 2015-06-11T20:16:35.210 回答
3

最后,我能够结合使用@Zikes 和@Scott 的答案来完成这项工作。首先,我按照@Zikes 的建议分离了关注点,所以我把它放在了product-list元素中。

<template>
  <template is="dom-if" if="{{loading}}">
    <paper-progress value="10" indeterminate="true" style="width:100%;"></paper-progress>
  <template>
  <get-products-service loading="{{loading}}"></get-products-service>
</template>

get-products-service元素中,我必须进行一些更改才能使其正常工作。出于某种原因,我不会将loading属性从iron-ajax集合中获取到true. 因此,@Zikes 的回答无法正常工作。我不得不做一些改变:

  1. loading将属性的值显式设置为true就在iron-ajax触发请求之前。
  2. 在触发事件时显式设置loadingto的值。falseon-response
  3. 为此,我loading通过删除readOnly: true;行更改了@Zikes 答案的属性。

使用@Scott 的建议,我通过以下方式减慢了速度:

this.async(function() {
        this.$.productsajax.generateRequest();
      }, 5000);

有机会看到progress-bar

生成的get-products-service元素如下所示:

<dom-module id="get-products-service">
  <style>
    :host {
      display: none;
    }
  </style>
  <template>
    <iron-ajax id="productsajax"
      url="http://localhost:3003/api/products"
      method='GET'
      on-response='productsLoaded'
      handleAs="json">
    </iron-ajax>
  </template>
</dom-module>

<script>
  Polymer({is: 'get-products-service',
    properties: {
     loading: {
      type: Boolean,
      notify: true,
      value: false
      }
    },
    //on-response callback
     productsLoaded: function(request) {
         this.loading = false;
     },

   //An observer method where ajax request is generated
    attributesReady: function(page) {
      //set the value of loading to true just before generating request
      this.loading = true;
      //slow things to get a chance to see the progress-bar
      this.async(function() {
        this.$.productsajax.generateRequest();
      }, 5000);
    }

  });
</script>

我相信@Zikes 答案也应该有效,我是未能正确实施它的人,所以我会接受它作为正确答案。

于 2015-06-12T18:10:38.280 回答
2

@Zikes 有正确的答案。我在这里补充了一个完整的实现(仅适用于 Chrome,x 平台需要一些调整):

<!doctype html>
<html>
<head>

  <meta charset="utf-8">

  <base href="http://milestech.net/components/">

  <link href="iron-ajax/iron-ajax.html" rel="import">
  <link href="paper-progress/paper-progress.html" rel="import">

</head>
<body>

  <use-service></use-service>

  <dom-module id="get-products-service">
    <template>

      <iron-ajax url="iron-ajax/bower.json" auto="{{go}}" handle-as="text" last-response="{{products}}"></iron-ajax>

    </template>
    <script>

      Polymer({

        properties: {
          products: {
            notify: true,
            value: null
          }
        },

        ready: function() {
          // this bit just because otherwise it's too fast to see
          this.async(function() {
            this.go = true;
          }, 1000);
        }
      });

    </script>
  </dom-module>

  <dom-module id="use-service">
    <template>

      <template is="dom-if" if="{{!products}}">
        <paper-progress value="10" indeterminate="true" style="width:100%;"></paper-progress>
      </template>

      <get-products-service products="{{products}}"></get-products-service>

      <pre>{{products}}</pre>

    </template>
    <script>

      Polymer({});

    </script>
  </dom-module>

</body>
</html>
于 2015-06-12T01:13:02.683 回答
0

在我的例子中,我想保持进度条在菜单区域中始终可见,并在做一些可能需要一些时间的工作时从不同的元素开始/停止它。

默认情况下,加载时进度是不确定的

<paper-progress id="working" indeterminate ></paper-progress>

我们有一个全局命名空间对象应用程序,我只是在其中添加一个函数,如下所示

  app.working = function(flag){
    document.querySelector("#working").indeterminate = flag;
  };

在那种情况下,当初始加载完成时,我只是做

app.working(false);

它可以稍后从应用程序中的任何元素启动/停止,只需执行

app.working(true);
// ... long process
app.working(false);
于 2016-06-23T17:52:05.060 回答
0

我知道这有点晚了,但我遇到了类似的困境并决定公开 API。这样我就可以显示 XHR 请求的确切进度百分比。

注意:非常哈克

我通过覆盖默认的 generateRequest() 方法来做到这一点,并添加了一些内容。

app.$.productsajax.generateRequest = function() {
  var request = (document.createElement('iron-request'));
  var requestOptions = this.toRequestOptions();
  ///**=============================================///
  ///**   Added to expose progress - Super Hacky  **///
  var me = this;
  request.ap_obs = function(a) {
    me.progress = a;
    me._notifyChange("progress")
  };
  request._addObserverEffect("progress", "ap_obs")
    ///**===========================================**///
  this.activeRequests.push(request);
  request.completes.then(
    this._boundHandleResponse
  ).catch(
    this._handleError.bind(this, request)
  ).then(
    this._discardRequest.bind(this, request)
  );
  request.send(requestOptions);
  this._setLastRequest(request);
  this._setLoading(true);
  this.fire('request', {
    request: request,
    options: requestOptions
  });
  return request;
}

所以现在你的元素看起来像:

<template>
  <iron-ajax url="iron-ajax/bower.json" progress="{{progress}}" loading="{{activePageReq}}" auto="{{go}}" handle-as="text" last-response="{{products}}"></iron-ajax>
  <paper-progress hide$="{{!activePageReq}}" value="{{progress.loaded}}" ,max="{{progress.total}}"></paper-progress>
</template>

于 2015-09-21T00:33:10.453 回答