聚合物1.0:铁分类清单 [英] Polymer 1.0: Sorting iron-list
问题描述
Google的Polymer创作者声称我们可以手动对<iron-list>
进行排序(解决此问题,也许?).
您可以设置
list.items = newItems
,这将刷新列表.
//this.$.list.items = this.items.sort(this._computeSort(val, ord));
//this.items = this.items.sort(this._computeSort(val, ord));
//this.items.sort(this._computeSort(val, ord));
//this.$.list.items = this.items.sort(this._computeSort(val, ord));
(我注释掉了所有尝试失败的内容.)
- 请注意,控制台日志会验证控制值.
- 还有一个内联控制值监视器.
- 这证明了排序逻辑.
<html>
<head>
<title>My Element</title>
<script data-require="polymer@*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents-lite.js"></script>
<script data-require="polymer@*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html"></script>
<base href="http://element-party.xyz/" />
<link rel="import" href="all-elements.html" />
</head>
<body>
<dom-module id="my-element">
<template>
<style>
h3 {
margin-bottom: 0px;
}
iron-list {
padding-bottom: 16px;
}
.item {
@apply(--layout-horizontal);
margin: 16px 16px 0 16px;
padding: 20px;
border-radius: 8px;
background-color: white;
border: 1px solid #ddd;
}
</style>
<firebase-collection location="https://dinosaur-facts.firebaseio.com/dinosaurs" data="{{items}}">
</firebase-collection>
<h3>Controls</h3>
<paper-dropdown-menu label="Sort by">
<paper-menu class="dropdown-content" selected="{{sortVal}}" attr-for-selected="data-sortby">
<paper-item data-sortby="order">Order</paper-item>
<paper-item data-sortby="height">Height</paper-item>
</paper-menu>
</paper-dropdown-menu>
<br>
<paper-toggle-button checked="{{reverse}}">Reverse</paper-toggle-button>
<br /><br />
<br><h3>Monitor Control Values</h3>
<div>Sort by: [[sortVal]]</div>
<div>Reverse: [[reverse]]</div>
<br><h3>Iron-List Output</h3>
<iron-list id="list" items="[[items]]" as="item">
<template>
<div class="item">
Name: [[item.__firebaseKey__]]<br />
Order: [[item.order]]<br />
Height: [[item.height]]
</div>
</template>
</iron-list>
</template>
<script>
(function() {
Polymer({
is: "my-element",
properties: {
items: {
type: Array,
},
sortVal: {
type: String,
value: 'order'
},
sortOrder: {
type: Number,
value: -1, // High to low
computed: '_computeSortOrder(reverse)'
}
},
observers: [
'sortChanged(sortVal, sortOrder)'
],
_computeSortOrder: function(bool) {
return bool ? 1 : -1;
},
sortChanged(val, ord) {
// Also tried what is commented out
//this.$.list.items = this.items.sort(this._computeSort(val, ord));
//this.items = this.items.sort(this._computeSort(val, ord));
//this.items.sort(this._computeSort(val, ord));
//this.$.list.items = this.items.sort(this._computeSort(val, ord));
console.log('ord: ' + ord); // All values logged
console.log('val: ' + val); // Logs are correct
console.log('items: ' + this.items); // See console log
},
_computeSort: function(val, ord) {
return function(a, b) {
if (a[val] === b[val]) {
return 0;
}
return (ord * (a[val] > b[val] ? 1 : -1));
};
}
});
})();
</script>
</dom-module>
<my-element></my-element>
</body>
</html>
每个@rob,聚合物松弛网站 :(请提供@arthur作为解决方案!)
这是一个排序的版本: http://jsbin.com/mabadi/2 /edit?html,输出
主要问题是,如果您更改数组的内容,Polymer不知道您已经这样做了(它无法在数组内部看到).因此,您需要创建数据的副本,对其进行排序,然后将其设置为新值
为firebaseItems和sortedItems设置一个单独的变量可能会有所帮助.这样一来,您就不会最终意外写回Firebase
还要确保给铁表一个高度
高度:100%或类似的值.并确保其容器也具有高度
http://jsbin.com/vizexodoyi/1/edit?html,输出
<html>
<head>
<title>My Element</title>
<script data-require="polymer@*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents-lite.js"></script>
<script data-require="polymer@*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html"></script>
<base href="http://element-party.xyz/" />
<link rel="import" href="all-elements.html" />
</head>
<body>
<dom-module id="my-element">
<template>
<style>
h3 {
margin-bottom: 0px;
}
iron-list {
padding-bottom: 16px;
height: 100%;
}
.item {
@apply(--layout-horizontal);
margin: 16px 16px 0 16px;
padding: 20px;
border-radius: 8px;
background-color: white;
border: 1px solid #ddd;
}
</style>
<firebase-collection location="https://dinosaur-facts.firebaseio.com/dinosaurs" data="{{items}}">
</firebase-collection>
<h3>Controls</h3>
<paper-dropdown-menu label="Sort by">
<paper-menu class="dropdown-content" selected="{{sortVal}}" attr-for-selected="data-sortby">
<paper-item data-sortby="order">Order</paper-item>
<paper-item data-sortby="height">Height</paper-item>
</paper-menu>
</paper-dropdown-menu>
<br>
<paper-toggle-button checked="{{reverse}}">Reverse</paper-toggle-button>
<br /><br />
<br><h3>Monitor Control Values</h3>
<div>Sort by: [[sortVal]]</div>
<div>Reverse: [[reverse]]</div>
<br><h3>Iron-List Output</h3>
<iron-list id="list" items="[[items]]" as="item">
<template>
<div class="item">
Name: [[item.__firebaseKey__]]<br />
Order: [[item.order]]<br />
Height: [[item.height]]
</div>
</template>
</iron-list>
</template>
<script>
(function() {
Polymer({
is: "my-element",
properties: {
items: {
type: Array,
},
sortVal: {
type: String,
value: 'order'
},
sortOrder: {
type: Number,
value: -1, // High to low
computed: '_computeSortOrder(reverse)'
}
},
observers: [
'sortChanged(sortVal, sortOrder)'
],
_computeSortOrder: function(bool) {
return bool ? 1 : -1;
},
sortChanged(val, ord) {
if (! this.items || this.items.length == 0) {
return;
}
var temp = Array.prototype.slice.call(this.items);
temp.sort(this._computeSort(val, ord));
this.items = temp;
//console.log('ord: ' + ord);
//console.log('val: ' + val);
//console.log('items: ' + this.items);
},
_computeSort: function(val, ord) {
return function(a, b) {
if (a[val] === b[val]) {
return 0;
}
return (ord * (a[val] > b[val] ? 1 : -1));
};
}
});
})();
</script>
</dom-module>
<my-element></my-element>
</body>
</html>
优化性能
对于那些对Array.prototype.slice.call(this.items)
感兴趣的人,您可能想研究这个问题和此处不同解决方案的性能比较.>
一项明显的性能改进可能是:
// Reference for below: https://stackoverflow.com/questions/3199588/fastest-way-to-convert-javascript-nodelist-to-array
//var temp = Array.prototype.slice.call(this.items);
var temp = [];
var i = this.items.length;
while(i--) {
//temp.unshift(this.items[i]);
temp[i] = this.items[i];
}
Google's Polymer creators claim we can manually sort <iron-list>
(resolving this issue, perhaps?).
Per @emmanuel on the Polymer Slack Site:
You can set
list.items = newItems
and that will refresh the list.
Here is my code. But it's not working. Please help.
This section of code seems to be the problem.//this.$.list.items = this.items.sort(this._computeSort(val, ord));
//this.items = this.items.sort(this._computeSort(val, ord));
//this.items.sort(this._computeSort(val, ord));
//this.$.list.items = this.items.sort(this._computeSort(val, ord));
(I commented out everything I tried that failed.)
- Notice the console logs verify the control values.
- There is also an inline control value monitor.
- This proves the sorting logic.
<html>
<head>
<title>My Element</title>
<script data-require="polymer@*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents-lite.js"></script>
<script data-require="polymer@*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html"></script>
<base href="http://element-party.xyz/" />
<link rel="import" href="all-elements.html" />
</head>
<body>
<dom-module id="my-element">
<template>
<style>
h3 {
margin-bottom: 0px;
}
iron-list {
padding-bottom: 16px;
}
.item {
@apply(--layout-horizontal);
margin: 16px 16px 0 16px;
padding: 20px;
border-radius: 8px;
background-color: white;
border: 1px solid #ddd;
}
</style>
<firebase-collection location="https://dinosaur-facts.firebaseio.com/dinosaurs" data="{{items}}">
</firebase-collection>
<h3>Controls</h3>
<paper-dropdown-menu label="Sort by">
<paper-menu class="dropdown-content" selected="{{sortVal}}" attr-for-selected="data-sortby">
<paper-item data-sortby="order">Order</paper-item>
<paper-item data-sortby="height">Height</paper-item>
</paper-menu>
</paper-dropdown-menu>
<br>
<paper-toggle-button checked="{{reverse}}">Reverse</paper-toggle-button>
<br /><br />
<br><h3>Monitor Control Values</h3>
<div>Sort by: [[sortVal]]</div>
<div>Reverse: [[reverse]]</div>
<br><h3>Iron-List Output</h3>
<iron-list id="list" items="[[items]]" as="item">
<template>
<div class="item">
Name: [[item.__firebaseKey__]]<br />
Order: [[item.order]]<br />
Height: [[item.height]]
</div>
</template>
</iron-list>
</template>
<script>
(function() {
Polymer({
is: "my-element",
properties: {
items: {
type: Array,
},
sortVal: {
type: String,
value: 'order'
},
sortOrder: {
type: Number,
value: -1, // High to low
computed: '_computeSortOrder(reverse)'
}
},
observers: [
'sortChanged(sortVal, sortOrder)'
],
_computeSortOrder: function(bool) {
return bool ? 1 : -1;
},
sortChanged(val, ord) {
// Also tried what is commented out
//this.$.list.items = this.items.sort(this._computeSort(val, ord));
//this.items = this.items.sort(this._computeSort(val, ord));
//this.items.sort(this._computeSort(val, ord));
//this.$.list.items = this.items.sort(this._computeSort(val, ord));
console.log('ord: ' + ord); // All values logged
console.log('val: ' + val); // Logs are correct
console.log('items: ' + this.items); // See console log
},
_computeSort: function(val, ord) {
return function(a, b) {
if (a[val] === b[val]) {
return 0;
}
return (ord * (a[val] > b[val] ? 1 : -1));
};
}
});
})();
</script>
</dom-module>
<my-element></my-element>
</body>
</html>
This JSBin proves the sorting logic.
Per @rob, Polymer Slack Site: (Credit to @arthur for the solution!)
here's a version that sorts: http://jsbin.com/mabadi/2/edit?html,output
the main issue is that if you change the contents of an array, polymer has no idea that you've done that (it can't see inside of an array). So you need to create a copy of your data, sort it, and set that as the new value
it may be helpful to have a separate variable for firebaseItems and sortedItems. That way you don't end up accidentally writing back to firebase
also make sure you give iron-list a height
height: 100% or something like that. And make sure its container has a height as well
http://jsbin.com/vizexodoyi/1/edit?html,output
<html>
<head>
<title>My Element</title>
<script data-require="polymer@*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents-lite.js"></script>
<script data-require="polymer@*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html"></script>
<base href="http://element-party.xyz/" />
<link rel="import" href="all-elements.html" />
</head>
<body>
<dom-module id="my-element">
<template>
<style>
h3 {
margin-bottom: 0px;
}
iron-list {
padding-bottom: 16px;
height: 100%;
}
.item {
@apply(--layout-horizontal);
margin: 16px 16px 0 16px;
padding: 20px;
border-radius: 8px;
background-color: white;
border: 1px solid #ddd;
}
</style>
<firebase-collection location="https://dinosaur-facts.firebaseio.com/dinosaurs" data="{{items}}">
</firebase-collection>
<h3>Controls</h3>
<paper-dropdown-menu label="Sort by">
<paper-menu class="dropdown-content" selected="{{sortVal}}" attr-for-selected="data-sortby">
<paper-item data-sortby="order">Order</paper-item>
<paper-item data-sortby="height">Height</paper-item>
</paper-menu>
</paper-dropdown-menu>
<br>
<paper-toggle-button checked="{{reverse}}">Reverse</paper-toggle-button>
<br /><br />
<br><h3>Monitor Control Values</h3>
<div>Sort by: [[sortVal]]</div>
<div>Reverse: [[reverse]]</div>
<br><h3>Iron-List Output</h3>
<iron-list id="list" items="[[items]]" as="item">
<template>
<div class="item">
Name: [[item.__firebaseKey__]]<br />
Order: [[item.order]]<br />
Height: [[item.height]]
</div>
</template>
</iron-list>
</template>
<script>
(function() {
Polymer({
is: "my-element",
properties: {
items: {
type: Array,
},
sortVal: {
type: String,
value: 'order'
},
sortOrder: {
type: Number,
value: -1, // High to low
computed: '_computeSortOrder(reverse)'
}
},
observers: [
'sortChanged(sortVal, sortOrder)'
],
_computeSortOrder: function(bool) {
return bool ? 1 : -1;
},
sortChanged(val, ord) {
if (! this.items || this.items.length == 0) {
return;
}
var temp = Array.prototype.slice.call(this.items);
temp.sort(this._computeSort(val, ord));
this.items = temp;
//console.log('ord: ' + ord);
//console.log('val: ' + val);
//console.log('items: ' + this.items);
},
_computeSort: function(val, ord) {
return function(a, b) {
if (a[val] === b[val]) {
return 0;
}
return (ord * (a[val] > b[val] ? 1 : -1));
};
}
});
})();
</script>
</dom-module>
<my-element></my-element>
</body>
</html>
Optimizing Performance
For those interested in Array.prototype.slice.call(this.items)
, you might want to study this SO question and the performance comparison of different solutions here.
One apparent performance improvement might be:
// Reference for below: https://stackoverflow.com/questions/3199588/fastest-way-to-convert-javascript-nodelist-to-array
//var temp = Array.prototype.slice.call(this.items);
var temp = [];
var i = this.items.length;
while(i--) {
//temp.unshift(this.items[i]);
temp[i] = this.items[i];
}
这篇关于聚合物1.0:铁分类清单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!