聚合物:变化不总是流过过滤器 [英] Polymer: Changes not always flowing through a filter

查看:155
本文介绍了聚合物:变化不总是流过过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我看到一个错误,如果我显示所有的数组元素,一切都很好。如果我通过使用 .slice()的数组的副本来响应我的数组更改,并将其放在另一个字段中,并显示为前N个元素过滤的字段,那么一切都好。但是,如果我刚刚显示原始的数组,通过最前面的N个元素过滤,那么DOM永远不会更新到更改。



这是一个代码删除的bug,问题: http://codepen.io/rictic/pen/ienJK?editors=101



全部代码:

 < 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 =importhref =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
< ul>
< template repeat ='{{result in}}'>
< li> {{r.value}} - {{r.name}}< / li>
< / template>
< / ul> processedResults |

r第一(5)
< ul>
< template repeat ='{{r in processedResults |第一(5)}}'>
< li> {{r.value}} - {{r.name}}< / li>
< / template>
< / ul>

r in results |第一(5)
< ul>
< template repeat ='{{r in results |第一(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' '];

Polymer('my-app',{
results:[{value:10,name:'root'}],
first:function(a,k){
//显示数组的第k个元素的过滤器
if(!a){
return a;
}
return a.slice(0 ,
},
domReady:function(){
//填充结果数组
for(var i = 0; i< 10; i ++){
this.results.push({value:i,name:names [i]});
}

//一次,对数组进行mutate和排序
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;
}
返回a.name.localeCompare(b.name);
});
} .bind(this),1000);
},
resultChanged:function(){
//复制this.results int o this.processedResults。
this.processedResults = this.results.slice();
}
});
< / script>


解决方案

我相信您可以在创建回调,一切都会工作。以下是示例CodePen 创建的回调是本地自定义元素的一部分,并在准备好之前执行(由Polymer添加以了解各种功能像数据绑定设置并准备摇滚)。我仍然模糊,为什么你必须这样做,所以我要求团队成员向我解释,我会留下另一个意见,当我知道更多:)



编辑



在与其中一位聚合物表达式的作者交谈之后,听起来你的原始代码应该已经工作,但是如果对象 model.results 指向是突变的,则过滤器当前不会重新运行。相反,如果路径 model.results 指向更改的对象,则它们才会重新运行。这似乎是一个过滤器的缺点,我们正在考虑改变行为,使其工作正常,因为您会期望。


I've got an array that I'd like to display the top N elements from. This array is mutated and kept sorted by another component in my app.

I'm seeing a bug though such that if I display all of the array elements everything is fine. If I respond to my array changing by taking a copy of the array with .slice() and putting that in another field and displaying that field filtered for the top N elements, then everything if fine. But if I just display the original array filtered through for the top N elements then the DOM is never updated to changes.

Here's a codepen reduction of the bug that shows off the problem: http://codepen.io/rictic/pen/ienJK?editors=101

Full code:

<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>

解决方案

I believe you can setup results in the created callback and everything will work. Here's an example CodePen. The created callback is part of native custom elements and executes before ready (which is added by Polymer to know when various features like data binding are setup and ready to rock). I'm still fuzzy as to why you have to do it this way so I've asked a member of the team to explain it to me and I'll leave another comment when I know more :)

edit

After speaking with one of the authors of polymer-expressions, it sounds like your original code should have worked but filters are not currently rerunning if the object model.results points to is mutated. Instead they only rerun if the path to the object that model.results points to changes. This seems like a shortcoming of filters and we're looking into changing the behavior so it works as you would expect.

这篇关于聚合物:变化不总是流过过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆