Data binding 聚合物:变化并不总是通过过滤器
我有一个数组,我想显示前N个元素。这个数组被我的应用程序中的另一个组件变异并保持排序 我看到了一个bug,如果我显示所有的数组元素,一切都很好。如果我通过使用Data binding 聚合物:变化并不总是通过过滤器,data-binding,polymer,Data Binding,Polymer,我有一个数组,我想显示前N个元素。这个数组被我的应用程序中的另一个组件变异并保持排序 我看到了一个bug,如果我显示所有的数组元素,一切都很好。如果我通过使用.slice()复制数组并将其放在另一个字段中并显示筛选出的前N个元素的字段来响应数组的更改,则一切正常。但是,如果我只显示经过筛选的前N个元素的原始数组,那么DOM永远不会根据更改进行更新 下面是一个代码笔减少的bug,它显示了问题: 完整代码: <script src="http://www.polymer-project.org
.slice()
复制数组并将其放在另一个字段中并显示筛选出的前N个元素的字段来响应数组的更改,则一切正常。但是,如果我只显示经过筛选的前N个元素的原始数组,那么DOM永远不会根据更改进行更新
下面是一个代码笔减少的bug,它显示了问题:
完整代码:
<script src="http://www.polymer-project.org/platform.js"></script><script src="http://www.polymer-project.org/components/web-animations-js/web-animations.js"></script><link rel="import" href="http://www.polymer-project.org/components/polymer/polymer.html">
<my-app></my-app>
<script>console.clear()</script>
<polymer-element name='my-app'>
<template>
<template if='{{results}}'>
r in results
<ul>
<template repeat='{{ r in results }}'>
<li>{{r.value}} - {{r.name}}</li>
</template>
</ul>
r in processedResults | first(5)
<ul>
<template repeat='{{ r in processedResults | first(5) }}'>
<li>{{r.value}} - {{r.name}}</li>
</template>
</ul>
r in results | first(5)
<ul>
<template repeat='{{ r in results | first(5) }}'>
<li>{{r.value}} - {{r.name}}</li>
</template>
</ul>
</template>
</template>
<script>
</script>
</polymer-element>
<script>
'use strict';
var names = ['Alice', 'Bob', 'Charline', 'Daryl', 'Elise', 'Franz', 'Geraldine', 'Happsburg', 'Irene', 'Jerome'];
Polymer('my-app', {
results: [{value: 10, name: 'root'}],
first: function(a, k) {
// A filterer to display the first k elements of an array.
if (!a) {
return a;
}
return a.slice(0, k);
},
domReady: function() {
// Populate the results array.
for (var i = 0; i < 10; i++) {
this.results.push({value: i, name: names[i]});
}
// Once a second, mutate and sort the array
setInterval(function() {
var randomChoice = Math.round(Math.random() * (this.results.length - 1));
this.results[randomChoice].value *= 2;
this.results.sort(function(a, b) {
if (a.value != b.value) {
return b.value - a.value;
}
return a.name.localeCompare(b.name);
});
}.bind(this), 1000);
},
resultsChanged: function() {
// Copy this.results into this.processedResults.
this.processedResults = this.results.slice();
}
});
</script>
控制台清除()
结果中的r
- {{r.value}}-{r.name}
r正在处理的结果|第一(5)
- {{r.value}}-{r.name}
结果中的r |第一(5)
- {{r.value}}-{r.name}
"严格使用",;
变量名称=['Alice'、'Bob'、'Charline'、'Daryl'、'Elise'、'Franz'、'Geraldine'、'Happsburg'、'Irene'、'Jerome'];
聚合物(“my-app”{
结果:[{value:10,name:'root'}],
第一:函数(a,k){
//用于显示数组的前k个元素的筛选器。
如果(!a){
返回a;
}
返回a.slice(0,k);
},
domReady:function(){
//填充结果数组。
对于(变量i=0;i<10;i++){
push({value:i,name:names[i]});
}
//每秒对数组进行一次变异和排序
setInterval(函数(){
var randomChoice=Math.round(Math.random()*(this.results.length-1));
此.results[randomChoice]。值*=2;
this.results.sort(函数(a,b){
如果(a.值!=b.值){
返回b.value-a.value;
}
返回a.name.localeCompare(b.name);
});
}.绑定(本),1000);
},
结果更改:函数(){
//将this.results复制到this.processedResults。
this.processedResults=this.results.slice();
}
});
我相信您可以在创建的
回调中设置结果,一切都会正常工作。给你。创建的回调是本机自定义元素的一部分,在就绪之前执行(由Polymer添加以了解数据绑定等各种功能何时设置并就绪)。我仍然不清楚为什么你必须这样做,所以我已经请团队的一名成员向我解释,当我知道更多时,我会留下另一条评论:)
编辑
在与polymer expressions的一位作者交谈后,听起来您的原始代码应该已经工作了,但是如果对象模型。结果指向发生了变异,则过滤器当前不会重新运行。相反,只有当指向model.results
的对象的路径指向更改时,它们才会重新运行。这似乎是筛选器的一个缺点,我们正在研究如何更改其行为,使其按预期工作。尝试在ready中初始化结果。如果属性是数组/对象,那么它们应该在那里初始化。我可以让它们工作。但是是的,看起来像一只虫子。除非完全修改对象属性,否则它不会观察对象属性的更改。在ready中初始化结果的好处是。在我真正的应用程序中,有另一个元素通过对服务器响应执行JSON.parse来获取结果
,然后在它将结果
提供给与上面我的应用程序
对应的元素后,它继续使用推送和排序来变异相同的数组。应用程序的行为仍然是如上所示的错误。非常有趣的是,您的更改解决了这个问题,如果我有更多的时间,我想我可以逐步查看代码,看看在哪里观察到了结果,以及在这些情况下,结果是如何不同的。啊,我应该考虑寻找聚合物表达式上现有的领域问题。看来其他人已经发现了这一点,从和评论。我已经订阅了这些问题,谢谢!具体而言,created
和ready
之间的区别在于,在将标记中设置的属性值转换为属性值之前调用created
。如果您的属性是对象或数组,则应在创建的中设置默认值,这将在Polymer将属性值(字符串)转换为JavaScript对象时为其提供类型提示。ready
回调在从属性初始化属性后被调用,所以您可以在脚本中使用这些值。另一方面,在ready
回调中设置属性值会覆盖标记中设置的任何值。