polymerdom-repeat

Polymer: forcing dom-repeat to recalculate all the item's index


I have a dom-repeat which displays a large list of items (about 9000 of them).

I am trying to only display part of the items, so that I don't end up with a gigantic scrollbar. For that I am using a dom-if that only shows items that have an index larger than 10.

When the dom-repeat is sorted or filtered, each item's index is recalculated, so it works very well.

Then I am using iron-scroll-threshold to detect when the user has scrolled to the bottom of the page, and then I am increasing the number of items displayed.

The problem is, this is not recalculating the index - in other words I can't figure out how to "redraw" the dom-repeat.

Is there a way to force a dom-repeat to recalculate all the index? Calling this.$.list.render() doesn't seem to do it.

<template id="list" is="dom-repeat" id="table" items="{{items}}" sort="{{sortFuntion}}">
  <template is="dom-if" if="{{isShowItem(index)}}">
    [[item.name]]<br />
  </template>
</template>

<iron-scroll-threshold scroll-target="document" on-lower-threshold="showMoreData">
</iron-scroll-threshold>

<script>
Polymer({
  is: 'my-element',
  properties: {
   limit: {type: Number, value: 10}
  },
  isShowItem: function(index) {
    return (index < this.limit);
    // we only show the items that have an index smaller than "limit" 
    // (the index is recalculated for each sort or filter, so it works well).
  },
  showMoreData: function() {
    // this is called by iron-scroll-threshold when we scroll down the page
    this.set("limit", this.limit + 10);
    // this is what doesn't seem to do anything:
    // (ideally we want it to recalculate each item's index)
    this.$.list.render(); 
  }
});
</script>

Solution

  • I never use filter or sort in a dom-repeat but instead insert a method in items. Then I can control all sorts of stuff.

    <template id="list" is="dom-repeat" id="table" items="[[_filterItems(items, scrollHeight)]]" sort="[[sortFuntion]]">
      ##code
    </template>
    
    ---
    <script>
      Polymer({
    
       ## properties and other methods
    
       _filterItems(items, scrollHeight) {  // ex. scrollHeight = 100
          var interpolationLevel = 5; // px
          var minAllowedItems = 10;
          var showThisManyItems = scrollHeight / interpolationLevel; // 100 / 5
          showThisManyItems (showThisManyItems < minAllowedItems) ? minAllowedItems : showThisManyItems; // 100 / 5 = 20, but min value == 10
    
          return items.filter(item, index) {
             return index < showThisManyItems;   // show this item if index < 20
          }
        },
      }
    </script>