Ділиться своїм рішенням, оскільки я не був повністю задоволений рештою. Моя проблема AfterViewChecked
полягає в тому, що іноді я прокручую вгору, і чомусь цей життєвий гачок називається, і він прокручує мене вниз, навіть якщо нових повідомлень не було. Я намагався використовувати, OnChanges
але це була проблема, яка привела мене до цього рішення. На жаль, використовуючи лише DoCheck
, він прокручувався вниз до винесення повідомлень, що теж не було корисно, тому я поєднав їх так, що DoCheck в основному вказує, AfterViewChecked
чи варто дзвонити scrollToBottom
.
Раді отримати відгуки.
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%