Ionic 4 离子含量滚动到底部

Posted

技术标签:

【中文标题】Ionic 4 离子含量滚动到底部【英文标题】:Ionic 4 ion-content scroll to bottom 【发布时间】:2019-08-02 15:36:55 【问题描述】:

我正在使用 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-angularContent 而不是来自@ionic/angularIonContent。我似乎无法在 Ionic 4 中使用 Content,因为它没有 scrollToBottom 方法。

【问题讨论】:

嘿!您可以在 ionViewDidEnter() 中调用滚动函数,而不是在 ngOnInit() 方法上调用。 【参考方案1】:

你可以通过 scrollToBottom()

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

ion-content添加一个ID

<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 就不起作用了。

【讨论】:

所以你的实现是正确的。 IonContent 导入不是必需的,您可以在不导入 IonContent 的情况下获取内容 ID。 我已将代码从导入 IonContent 更改为内容 ID。起初它不起作用,但是我尝试在ionViewDidEnter() 中调用this.scrollToBottomOnInit(),现在它可以正常工作了。我认为这可能是由于在消息加载之前调用this.scrollToBottomOnInit() 引起的 好电话。如果您从导航堆栈返回,ngOnInit 不会触发, ionViewWillEnter / ionViewDidEnter 会。也许您也可以在订阅接收到的数据后调用 scrollToBottom 方法。因此,当您的数据进入时,scrollToBottom 被激活。没试过,只是建议尝试一下;) 啊,是的,我也应该将它用于订阅的数据。感谢您的提醒。我想你可以编辑你的答案,我会接受的。 :D 只是为了说明:添加一些延迟可能会使其工作。例如:setTimeout(()=&gt;this.scrollToBottomOnInit();,200); 【参考方案2】:

由于最近对 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。 发布本文时使用的离子版本如下所示。

Ionic CLI                     : 5.4.13
Ionic Framework               : @ionic/angular 4.11.3
@angular/cli                  : 8.1.3

【讨论】:

作品,2020 年 2 月确认 setTimeout 修复了时间问题。我正在向ion-content 添加一个元素,然后向下滚动。但是该元素是在向下滚动事件之后添加的。 setTimeout 修复了它。【参考方案3】:

您的大部分代码都很好。您只需要在 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 是与您尝试在其中实现该功能的页面关联的模块。

【讨论】:

【参考方案4】:

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

1.

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

【讨论】:

【参考方案5】:

这对我来说适用于 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);
  

【讨论】:

【参考方案6】:

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

.ts

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

/.. 类声明 .../

@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);
    ); 

【讨论】:

这对我来说是最好的解决方案。完美运行谢谢! 谢谢,B 雪。【参考方案7】:
@ViewChild(IonContent) content: IonContent;
scrollToBottom() 
    setTimeout(() => 
      if (this.content.scrollToBottom) 
        this.content.scrollToBottom();
      
    , 400);
  

函数使用的任何地方:

this.scrollToBottom();

【讨论】:

【参考方案8】:

A mi me funcionó con la implementacion de AfterViewChecked del ciclo de vida de angular en angular 9 con fecha 2020 年 10 月 30 日

    重要

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

    import IonContent from '@ionic/angular';

    实现 AfterViewChecked

    export class PublicationsProductPage implements AfterViewChecked

    Cear el metodo scrollToBottom

    scrollToBottom() this.content.scrollToBottom();

    Llamar el metodo scrollToBottom desde la implementationación de AfterViewChecked

    ngAfterViewChecked() this.scrollToBottom();

con este codigo te aseguras de que siempre se dirija al final del ionconten

【讨论】:

以上是关于Ionic 4 离子含量滚动到底部的主要内容,如果未能解决你的问题,请参考以下文章

ionic 3.2 - 如何禁用离子含量的滚动?

键盘显示时离子含量未正确调整

ionic 视图滚动到顶部

如何在 ionic2 中使用 content.scrollTo() 进行离子滚动?

ion-textarea autoGrow 在输入时滚动到顶部

离子可滚动标签