6

I've been trying to keep scroll position of element holding a grid with hundreds of rows of data. Right now it's set with overflow-y: auto. If I use router to go to different page and than go back I'd like the scroll to be in the same position. I thought that using ngAfterViewInit will do the trick but unfortunately it doesn't work. If I use the console to fire up the set position command it works fine. I guess the problem is with rows still being loaded and not yet rendered when calling ngAfterViewInit .

@Component({ selector: 'grid', templateUrl: './grid.component.html', styleUrls: ['./grid.component.scss'] }) export class GridComponent implements OnInit, OnDestroy { @Input() rows: Array<Row>; @Input() someKindOfGridId: string; localGridConfigValue: ILocalGridConfigValue; constructor(private configService: ConfigService) { } ngOnInit() { this.localGridConfigValue = this.configService.getConfigForCurrentGrid(this.someKindOfGridId); } ngAfterViewInit(){ document.getElementById(this.someKindOfGridId).scrollTop = this.localGridConfigValue.gridScrollTopPos; } ngOnDestroy() { this.localGridConfigValue.gridScrollTopPos = document.getElementById(this.someKindOfGridId).scrollTop; } } 

I'm still learning angular and any help will be greatly appreciated.

Regards.

2
  • It doesn't directly solve your issue but this might help figure it out - stackoverflow.com/questions/39601026/… Commented Nov 16, 2017 at 20:51
  • 1
    You should look into angular's DoCheck lifecycle hook. It allows you to implement a custom change detection hook. In your case a hook that detects that your dom is completely loaded. Commented Nov 16, 2017 at 21:55

2 Answers 2

3

I managed to solve this using tip from @Andresson but DoCheck wasn't enough and I used ngAfterViewChecked instead. The important thing is I had to make sure that setting scroll position will be set off only once.

@Component({ selector: 'grid', templateUrl: './grid.component.html', styleUrls: ['./grid.component.scss'] }) export class GridComponent implements OnInit, OnDestroy { @Input() rows: Array<Row>; @Input() someKindOfGridId: string; localGridConfigValue: ILocalGridConfigValue; rowsCount: number = 0; scrolled: boolean = false; constructor(private configService: ConfigService) { } ngOnInit() { this.localGridConfigValue = this.configService.getConfigForCurrentGrid(this.someKindOfGridId); this.scrolled = false; } ngAfterViewChecked() { let newRowsCount = this.rows.length; if (newRowsCount <= 0 || !this.rowsCountChanged(newRowsCount) || this.scrolled) return; document.getElementById(this.someKindOfGridId).scrollTop = this.localGridConfigValue.gridScrollTopPos; this.rowsCount = newRowsCount; this.scrolled = true; } private rowsCountChanged(newRowsCount: number): boolean { return newRowsCount !== this.rowsCount; } ngOnDestroy() { this.localGridConfigValue.gridScrollTopPos = document.getElementById(this.someKindOfGridId).scrollTop; this.scrolled = false; } } 
Sign up to request clarification or add additional context in comments.

Comments

1

Solution from @MateuszMigała works. We can improve it by checking for changes to the collection.

import { Component, IterableDiffers, OnInit } from '@angular/core'; @Component({ selector: 'grid', templateUrl: './grid.component.html', styleUrls: ['./grid.component.scss'] }) export class GridComponent implements OnInit, OnDestroy { @Input() rows: Array<Row>; @Input() someKindOfGridId: string; localGridConfigValue: ILocalGridConfigValue; rowsCount: number = 0; scrolled: boolean = false; private iterableDiffer; constructor(private configService: ConfigService, private iterableDiffers: IterableDiffers) { this.iterableDiffer = iterableDiffers.find([]).create(null); } ngOnInit() { this.localGridConfigValue = this.configService.getConfigForCurrentGrid(this.someKindOfGridId); this.scrolled = false; } ngAfterViewChecked() { if (this.scrolled) { return; } else { let changes = this.iterableDiffer.diff(this.rows); if (!changes) return; document.getElementById(this.someKindOfGridId).scrollTop = this.localGridConfigValue.gridScrollTopPos; this.scrolled = true; } } ngOnDestroy() { this.localGridConfigValue.gridScrollTopPos = document.getElementById(this.someKindOfGridId).scrollTop; this.scrolled = false; } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.