Data binding 聚合物:变化并不总是通过过滤器

Data binding 聚合物:变化并不总是通过过滤器,data-binding,polymer,Data Binding,Polymer,我有一个数组,我想显示前N个元素。这个数组被我的应用程序中的另一个组件变异并保持排序 我看到了一个bug,如果我显示所有的数组元素,一切都很好。如果我通过使用.slice()复制数组并将其放在另一个字段中并显示筛选出的前N个元素的字段来响应数组的更改,则一切正常。但是,如果我只显示经过筛选的前N个元素的原始数组,那么DOM永远不会根据更改进行更新 下面是一个代码笔减少的bug,它显示了问题: 完整代码: <script src="http://www.polymer-project.org

我有一个数组,我想显示前N个元素。这个数组被我的应用程序中的另一个组件变异并保持排序

我看到了一个bug,如果我显示所有的数组元素,一切都很好。如果我通过使用
.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
回调中设置属性值会覆盖标记中设置的任何值。