Ionic 4 离子含量滚动到底部

Ionic 4 ion-content scroll to bottom

我正在使用 Ionic 4 创建一个聊天页面,我试图让它自动滚动到页面底部。我是这样做的,但没有用:

import { IonContent } from "@ionic/angular";

export class ChatroomPage implements OnInit {
    messageForm: FormGroup;
    messages: any[];
    messenger: any;
    @ViewChild(IonContent) content: IonContent;

    constructor(
        private navExtras: NavExtrasService,
        private api: RestApiService,
        private httpNative: HTTP
    ) { }

    ngOnInit() {
        this.content.scrollToBottom(300);
    }
}

在 html 文件中:

<ion-header>
    <ion-toolbar color="primary">
        <ion-title>Chatroom</ion-title>
            </ion-toolbar>
        </ion-header>

        <!-- display previous message -->
        <ion-content padding id="content"> 

        <ion-list>
            <ion-item *ngFor="let message of messages">
                {{ message.message }}
            </ion-item>
        </ion-list>

        </ion-content>

    <!-- chat message input -->
    <ion-footer>
        <form [formGroup]="messageForm" (submit)="sendMessage()" (keydown.enter)="sendMessage()">
            <ion-input formControlName="message" type="text" placeholder="Enter your message"></ion-input>
            <ion-button type="submit">Send</ion-button>
        </form>
    </ion-footer>

显示的错误是:

ng:///ChatroomPageModule/ChatroomPage_Host.ngfactory.js:5 ERROR TypeError: Cannot read property 'scrollToBottom' of undefined

请赐教我做错了什么。我发现的大多数教程都使用 Ionic 3,它们使用 ionic-angular 中的 Content 而不是 @ionic/angular 中的 IonContent。我似乎无法在 Ionic 4 中使用 Content,因为它没有 scrollToBottom 方法。

您可以使用 scrollToBottom()

方法到达内容底部
scrollToBottom(duration?: number) => Promise<void>

将 ID 添加到 ion-content

<ion-content #content>
</ion-content>

获取 .ts 中的内容 ID 并使用选定的持续时间调用 scrollToBottom 方法

@ViewChild('content') private content: any;

ngOnInit() {
  this.scrollToBottomOnInit();
}

scrollToBottomOnInit() {
  this.content.scrollToBottom(300);
}

https://ionicframework.com/docs/api/content

编辑:

ViewChild 使用提供的内容 ID 获取正确的数据

@ViewChild('content') private content: any;

ngOnInit 与 ionViewDidEnter / ionViewWillEnter

如果您从导航堆栈返回,ngOnInit 不会触发,ionViewWillEnter / ionViewDidEnter 会触发。因此,如果您将函数放在 ngOnInit 中,则如果您向后导航,则 scrollToBottom 将不起作用。

Tomas Vancoillie 是对的,但是当您添加新文本并添加到列表时,它不会将其推到输入文本之上。因此,要再次将文本推送到数组并将视图更新到底部,请使用 ngZone。

1.

import { Component, ViewChild,NgZone } from '@angular/core';
  1. 在构造函数中添加
public _zone: NgZone
  1. 调用你的函数
this._zone.run(() => {
  setTimeout(() => {
    this.contentchat.scrollToBottom(300);
  });
}); 

你的大部分代码都没有问题。在 Ionic 4 中,您只需要做 2 处更改,这应该对您有用。更改如下:

更改 1(HTML 文件):

替换:

<ion-content padding id="content">

与:

<ion-content padding #content>

更改 2 (TS 文件):

替换:

scrollToBottomOnInit() {
  this.content.scrollToBottom(300);
}

与:

scrollToBottomOnInit() {
    setTimeout(() => {
        if (this.content.scrollToBottom) {
            this.content.scrollToBottom(400);
        }
    }, 500);
}

注意:

如果您不导入 IonContent(类似于您已经导入的方式),代码将无法编译,您将看到如下控制台错误:

ERROR Error: Uncaught (in promise): ReferenceError: Cannot access 'MessagesPageModule' before initialization

其中 MessagesPageModule 是与您尝试在其中实现该功能的页面关联的模块。

这对我有用2019 年 12 月

.html

<ion-content #content>

</ion-content>

.ts

@ViewChild('content', { static: false }) content: IonContent;

constructor(){}

 ngOnInit(): void {
    this.scrollToBottom();
  }


 scrollToBottom(): void {
    this.content.scrollToBottom(300);
  }

由于 ionic 4 最近发生了变化,我发现建议答案中的代码不再适用于我。希望对各位新手有所帮助。

import { IonContent } from '@ionic/angular';

export class IonicPage implements OnInit {
@ViewChild(IonContent, {read: IonContent, static: false}) myContent: IonContent;

  constructor() {}

  ScrollToBottom(){
    setTimeout(() => {
      this.myContent.scrollToBottom(300);
   }, 1000);

  }
}

没有在 .html 文件中为 指定 ID

官方文档参考ion-content。 post.

时使用的 Ionic 版本如下所列
Ionic CLI                     : 5.4.13
Ionic Framework               : @ionic/angular 4.11.3
@angular/cli                  : 8.1.3

这终于对我有用了。你可以试试看。

.ts

import { Component, OnInit, ViewChild, NgZone } from '@angular/core';

/..class声明.../

@ViewChild('content') content : IonContent;

constructor(public _zone: NgZone){
}

ngOnInit(): void {
    this.scrollToBottom();
}

scrollToBottom()
{
    this._zone.run(() => {

      const duration : number = 300;

      setTimeout(() => {
        
        this.content.scrollToBottom(duration).then(()=>{

          setTimeout(()=>{

            this.content.getScrollElement().then((element:any)=>{

              if (element.scrollTopMax != element.scrollTop)
              {
                // trigger scroll again.
                this.content.scrollToBottom(duration).then(()=>{

                  // loaded... do something

                });
              }
              else
              {
                // loaded... do something
              }
            });
          });
        });

      },20);
    }); 
}

在 angular 的生命周期中实施 AfterViewChecked 对我有用 在 angular 9 日期 10/30/2020

  1. 导入

    import { Component, OnInit, ViewChild, AfterViewChecked } from '@angular/core';

    import { IonContent } from '@ionic/angular';

  2. 实施 AfterViewChecked

    export class PublicationsProductPage implements AfterViewChecked {

  3. 创建 scrollToBottom 方法

    scrollToBottom() { this.content.scrollToBottom(); }

  4. 从 AfterViewChecked 实现中调用 scrollToBottom 方法

    ngAfterViewChecked(){ this.scrollToBottom(); }

使用此代码确保它始终到达 ioncontent

的末尾
@ViewChild(IonContent) content: IonContent;
scrollToBottom() {
    setTimeout(() => {
      if (this.content.scrollToBottom) {
        this.content.scrollToBottom();
      }
    }, 400);
  }

函数中的任何地方使用:

this.scrollToBottom();