Polymer: Changes not always flowing through a filter

徘徊边缘 提交于 2019-12-11 07:20:44

问题


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>

回答1:


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.



来源:https://stackoverflow.com/questions/23706775/polymer-changes-not-always-flowing-through-a-filter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!