在加载 iron-ajax 时显示 Polymer 不确定的纸张进度
Show Polymer indeterminate paper-progress when iron-ajax is loading
当 iron-ajax
请求正在进行但没有成功时,我正在尝试显示论文进度。下面是承载 iron-ajax
请求的自定义元素 get-products-service
和承载 paper-progress
.
的 products-list
的代码
这是全部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>
你最好的选择是分开你的顾虑。首先,你的 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-service
和 paper-progress
就不必了解彼此,并且在您的应用程序的其他地方应该更具可组合性。
@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>
最后,我能够结合使用@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
元素中,我必须进行一些更改才能使其正常工作。出于某种原因,我不会将 iron-ajax
中的 loading
属性 设置为 true
。因此@Zikes 的回答不会像以前那样有效。我不得不做一些改变:
- 在触发
iron-ajax
请求之前将 loading
属性 的值显式设置为 true
。
- 当触发
on-response
事件时,将 loading
的值显式设置为 false
。
- 为了这个工作,我通过删除
readOnly: true;
行更改了@Zikes 答案的 loading
属性。
根据@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 的答案也应该有效,我是未能正确实施它的人,所以我会接受它作为正确答案。
我知道有点晚了,但我 运行 陷入了类似的困境并决定公开 API。
这样我就可以显示 XHR 请求的确切进度百分比。
注意:非常 Hacky
我通过覆盖默认的 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>
在我的例子中,我想让进度条在菜单区域始终可见,并在执行一些可能需要一些时间的工作时从不同的元素启动/停止它。
加载时默认进度不确定
<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);
当 iron-ajax
请求正在进行但没有成功时,我正在尝试显示论文进度。下面是承载 iron-ajax
请求的自定义元素 get-products-service
和承载 paper-progress
.
products-list
的代码
这是全部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>
你最好的选择是分开你的顾虑。首先,你的 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-service
和 paper-progress
就不必了解彼此,并且在您的应用程序的其他地方应该更具可组合性。
@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>
最后,我能够结合使用@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
元素中,我必须进行一些更改才能使其正常工作。出于某种原因,我不会将 iron-ajax
中的 loading
属性 设置为 true
。因此@Zikes 的回答不会像以前那样有效。我不得不做一些改变:
- 在触发
iron-ajax
请求之前将loading
属性 的值显式设置为true
。 - 当触发
on-response
事件时,将loading
的值显式设置为false
。 - 为了这个工作,我通过删除
readOnly: true;
行更改了@Zikes 答案的loading
属性。
根据@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 的答案也应该有效,我是未能正确实施它的人,所以我会接受它作为正确答案。
我知道有点晚了,但我 运行 陷入了类似的困境并决定公开 API。 这样我就可以显示 XHR 请求的确切进度百分比。
注意:非常 Hacky
我通过覆盖默认的 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>
在我的例子中,我想让进度条在菜单区域始终可见,并在执行一些可能需要一些时间的工作时从不同的元素启动/停止它。
加载时默认进度不确定
<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);