til*_*lly 2 javascript angular
我一直在推迟解决我已经有一段时间的错误了。我有以下聊天窗口:
我显示消息的窗口是一个单独的组件(chat-window.component.ts)。我想使用ngOnChanges滚动到底部。
当我们从父组件接收到带有消息的会话(通过异步请求从服务器接收消息)时,我们想要滚动到window元素的底部。我们通过this.scrollToBottom()在ngOnChanges生命周期挂钩中调用类的方法来实现。
确实会调用this.scrollToBottom,但不会滚动到元素的底部。有人知道为什么吗?
chat-window.component.ts:在ngOnchanges中,我们在调用this.scrollToBottom()之前会做一些同步处理
export class ChatboxWindowComponent implements OnChanges, OnInit, AfterViewChecked {
@Input('conversation') conversation;
@ViewChild('window') window;
constructor() { }
ngOnChanges() {
// If the date separators have already been added once, we avoid doing it a second time
const existingDateObj = this.conversation.messages.findIndex((item, i) => item.dateObj);
if (existingDateObj === -1) {
this.conversation.messages.forEach( (item, index, array) => {
if (index !== 0) {
const date1 = new Date(array[index - 1].date);
const date2 = new Date(item.date);
if (date2.getDate() !== date1.getDate() || date2.getMonth() !== date1.getMonth()) {
this.conversation.messages.splice(index, 0, {date: date2, dateObj: true});
console.log(this.conversation.messages.length);
}
}
});
}
this.scrollToBottom();
}
ngOnInit() {
}
ngAfterViewChecked() {
}
isItMyMsg(msg) {
return msg.from._id === this.conversation.otherUser.userId;
}
scrollToBottom() {
try {
console.log('scrollToBottom called');
this.window.nativeElement.top = this.window.nativeElement.scrollHeight;
} catch (err) {}
}
}
Run Code Online (Sandbox Code Playgroud)
chat-window.component.html
<div #window class="window">
<ng-container *ngFor="let message of conversation.messages">
<div class="date-container" *ngIf="!message.msg; else windowMsg">
<p class="date">{{message.date | amDateFormat:'LL'}}</p>
</div>
<ng-template #windowMsg>
<p
class="window__message"
[ngClass]="{
'window__message--left': isItMyMsg(message),
'window__message--right': !isItMyMsg(message)
}"
>
{{message.msg}}
</p>
</ng-template>
</ng-container>
</div>
Run Code Online (Sandbox Code Playgroud)
滚动不起作用,因为调用时尚未渲染消息列表scrollToBottom。为了在显示消息后滚动,请在消息容器上设置模板引用变量(例如#messageContainer):
<ng-container #messageContainer *ngFor="let message of conversation.messages">
...
</ng-container>
Run Code Online (Sandbox Code Playgroud)
在代码中,您可以使用来访问这些元素,ViewChildren并在QueryList.changes触发事件时滚动窗口:
@ViewChildren("messageContainer") messageContainers: QueryList<ElementRef>;
ngAfterViewInit() {
this.scrollToBottom(); // For messsages already present
this.messageContainers.changes.subscribe((list: QueryList<ElementRef>) => {
this.scrollToBottom(); // For messages added later
});
}
Run Code Online (Sandbox Code Playgroud)