Chia sẻ giải pháp của tôi, vì tôi không hoàn toàn hài lòng với phần còn lại. Vấn đề của tôi AfterViewChecked
là đôi khi tôi đang cuộn lên, và vì một lý do nào đó, cái móc cuộc sống này được gọi và nó cuộn tôi xuống ngay cả khi không có tin nhắn mới. Tôi đã thử sử dụng OnChanges
nhưng đây là một vấn đề, dẫn tôi đến giải pháp này . Thật không may, chỉ sử dụng DoCheck
, nó đã cuộn xuống trước khi các thông báo được hiển thị, điều này cũng không hữu ích, vì vậy tôi kết hợp chúng để DoCheck về cơ bản chỉ ra AfterViewChecked
liệu nó có nên gọi hay không scrollToBottom
.
Rất vui khi nhận được phản hồi.
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%