Reputation: 7856
import { Component, Input, AfterViewInit, ViewChild } from '@angular/core';
@Component({
selector: 'hello',
template: `<h1>Hello {{name}}!</h1>
<div #commentDetailWrapper style="height: 100px; border: 1px solid; width: 100px; overflow-y:scroll ">
<div *ngFor="let axe of axes"><button>Filler</button></div>
</div>
<button (click)='add()'>Add More</button>
`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent implements AfterViewInit {
@Input() name: string;
@ViewChild('commentDetailWrapper', { static: false }) commentDetailWrapper;
axes = Array(10);
add() {
this.axes.push(Array(1));
const el: HTMLDivElement = this.commentDetailWrapper.nativeElement;
el.scrollTop = el.scrollHeight;
}
ngAfterViewInit() {
const el: HTMLDivElement = this.commentDetailWrapper.nativeElement;
el.scrollTop = el.scrollHeight;
}
}
This works on Default it scrolls to the last element how do I scroll to bottom when I add a new element by clicking on the add More
button
Here is the problem Working Demo on Stackblitz
Desired Result: scroll to bottom on clicking add more button
Upvotes: 1
Views: 1861
Reputation: 2294
Executing the scroll after a timeout solves the problem. Since the view is not updated when you try to scroll.
Solution 1:
using AfterViewChecked
hook,
export class HelloComponent implements AfterViewInit, AfterViewChecked {
added:boolean;
...
add() {
this.axes.push(Array(1));
this.added = true;
}
ngAfterViewChecked() {
// run only when new axe is added
if(this.added) {
const el: HTMLDivElement = this.commentDetailWrapper.nativeElement;
el.scrollTop = el.scrollHeight;
this.added = false;
}
}
...
}
Solution 2:
using setTimeout
,
...
add() {
this.axes.push(Array(1));
const el: HTMLDivElement = this.commentDetailWrapper.nativeElement;
setTimeout(() => {
el.scrollTop = el.scrollHeight;
});
}
...
Solution 1a:
Separating the component and make the input data immutable. Used ChangeDetectionStrategy.OnPush
for the implementation
https://stackblitz.com/edit/angular-2zjf4a
Upvotes: 1