【问题标题】:Angular: unable to scroll down to bottom in elementAngular:无法在元素中向下滚动到底部
【发布时间】:2019-04-07 00:19:19
【问题描述】:

我一直在推迟修复这个我已经有一段时间的错误。我有以下聊天窗口:

我显示消息的窗口是一个单独的组件 (chat-window.component.ts)。我想用 ngOnChanges 滚动到底部。

当我们从父组件接收到与消息的对话时,它是通过异步请求从服务器接收的,我们希望滚动到窗口元素的底部。我们通过在 ngOnChanges 生命周期钩子中调用类的 this.scrollToBottom() 方法来做到这一点。

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) {}
  }
}

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>

【问题讨论】:

  • 我忘记添加模板了。一秒钟就上来了
  • 尝试使用scrollTop 而不是top 像这样this.window.nativeElement.scrollTop = this.window.nativeElement.scrollHeight
  • 我编辑了它。它没有解决问题。我做了 4 个 console.logs 来看看他们给了我什么。我在this.window.nativeElement.scrollTop = this.window.nativeElement.scrollHeight 之前做了两个(scrollTop 和 scrollheight),之后做了两个。之前的结果是 scrollTop 为 0,scrollHeight 为 229。
  • 测试:延迟滚动后是否有效:setTimeout(() =&gt; { this.scrollToBottom(); }, 500);?
  • 希望这个链接能帮到你stackoverflow.com/questions/35232731/…

标签: javascript angular


【解决方案1】:

您可以将以下代码添加到您的 HTML 元素中。

#window [scrollTop]="window.scrollHeight" *ngIf="messages.length > 0"

根据您的代码示例完整代码如下,

<div #window [scrollTop]="window.scrollHeight" *ngIf="messages.length > 0" 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>

这对我有用。 (目前,我使用的是 Angular 11)??

【讨论】:

    【解决方案2】:

    滚动不起作用,因为当您调用scrollToBottom 时消息列表尚未呈现。为了在消息显示后滚动,请在消息容器上设置template reference variable(例如#messageContainer):

    <ng-container #messageContainer *ngFor="let message of conversation.messages">
      ...
    </ng-container>
    

    在代码中,您可以使用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
      });
    }
    

    【讨论】:

    • 很好的答案。非常感谢康纳
    猜你喜欢
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多