Berbagi solusi saya, karena saya tidak sepenuhnya puas dengan yang lain. Masalah saya AfterViewChecked
adalah terkadang saya menggulir ke atas, dan untuk beberapa alasan, pengait kehidupan ini dipanggil dan menggulung saya ke bawah meskipun tidak ada pesan baru. Saya mencoba menggunakan OnChanges
tetapi ini adalah masalah, yang mengarahkan saya ke solusi ini . Sayangnya, hanya dengan menggunakan DoCheck
, itu bergulir ke bawah sebelum pesan dirender, yang juga tidak berguna, jadi saya menggabungkannya sehingga DoCheck pada dasarnya menunjukkan AfterViewChecked
apakah itu harus memanggil scrollToBottom
.
Senang menerima umpan balik.
export class ChatComponent implements DoCheck, AfterViewChecked {
@Input() public messages: Message[] = [];
@ViewChild('scrollable') private scrollable: ElementRef;
private shouldScrollDown: boolean;
private iterableDiffer;
constructor(private iterableDiffers: IterableDiffers) {
this.iterableDiffer = this.iterableDiffers.find([]).create(null);
}
ngDoCheck(): void {
if (this.iterableDiffer.diff(this.messages)) {
this.numberOfMessagesChanged = true;
}
}
ngAfterViewChecked(): void {
const isScrolledDown = Math.abs(this.scrollable.nativeElement.scrollHeight - this.scrollable.nativeElement.scrollTop - this.scrollable.nativeElement.clientHeight) <= 3.0;
if (this.numberOfMessagesChanged && !isScrolledDown) {
this.scrollToBottom();
this.numberOfMessagesChanged = false;
}
}
scrollToBottom() {
try {
this.scrollable.nativeElement.scrollTop = this.scrollable.nativeElement.scrollHeight;
} catch (e) {
console.error(e);
}
}
}
chat.component.html
<div class="chat-wrapper">
<div class="chat-messages-holder" #scrollable>
<app-chat-message *ngFor="let message of messages" [message]="message">
</app-chat-message>
</div>
<div class="chat-input-holder">
<app-chat-input (send)="onSend($event)"></app-chat-input>
</div>
</div>
chat.component.sass
.chat-wrapper
display: flex
justify-content: center
align-items: center
flex-direction: column
height: 100%
.chat-messages-holder
overflow-y: scroll !important
overflow-x: hidden
width: 100%
height: 100%