角度:无法向下滚动到元素的底部

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)

Con*_*Fan 5

滚动不起作用,因为调用时尚未渲染消息列表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)