14

I have a list that has many items and each item can be selected. For this I use Angular Material Virtual Scroll. When an item is selected, the selected item is highlighted and then is saved on the server. When I refresh the page, the selected item comes from the server and is again highlighted.

My code looks like

<cdk-virtual-scroll-viewport itemSize="40" class="wrapper">
  <div *cdkVirtualFor="let item of list"
       [class.selected]="item.id === selectedItem.id">
  </div>
</cdk-virtual-scroll-viewport>

The problem is that if a select an item that is down in the list, it is highlighted, but I have to scroll down to the list to see it. I want to programmatically scroll down to it when that item comes from the server.

I the docs there is a scrollToIndex method. Where I can find an instance of FixedSizeVirtualScrollStrategy, so I can call this method?

msanford
  • 10,127
  • 8
  • 56
  • 83
MTZ
  • 823
  • 2
  • 14
  • 23

1 Answers1

21

Sure, you will need to get a reference to the CdkVirtualScrollViewport instance.

@ViewChild(CdkVirtualScrollViewport) viewPort: CdkVirtualScrollViewport;

scrollToMiddle(){
  this.viewPort.scrollToIndex(list.length/2, "smooth");
}

An example can be found in this stackblitz

For the requirement of scrolling to the index of the selected element in the list, you could do the following:

ngAfterViewInit(){
  const selectedIndex = this.list.findIndex(elem => elem.id === this.selectedItem.id);
   if(selectedIndex > -1){
     this.viewPort.scrollToIndex(selectedIndex);
   }
}

Note: this assumes that the list is already loaded during the ngAfterViewInit lifehook. As you havent provided more information about how the list value is set, this is the best that I can provide.

Jota.Toledo
  • 22,272
  • 8
  • 48
  • 63
  • Thanks! Just one short question: what if I have two lists? (Duplicate the list in the template in the stackblitz example) How can I scroll the second one? – MTZ Feb 06 '19 at 13:08
  • You will need to bind either through a specific child reference as explained here https://blog.angular-university.io/angular-viewchild/ section _Using @ViewChild to inject a reference to the DOM element of a component_ – Jota.Toledo Feb 06 '19 at 13:15
  • And by the way... Why did you called the method on a `CdkVirtualScrollViewport `object? It supposed to be called on a `FixedSizeVirtualScrollStrategy` object – MTZ Feb 06 '19 at 13:26
  • AFAIK the `FixedSizeVirtualScrollStrategy` is an implementation detail and you cant directly access it in this case. The closest that you could get to it would by by binding the viewport with the `CdkFixedSizeVirtualScroll` instead of `CdkVirtualScrollViewport`, but I dont see any advantage from it in this use case. – Jota.Toledo Feb 06 '19 at 13:26