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-angular
的Content
而不是来自@ionic/angular
的IonContent
。我似乎无法在 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(()=>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 文件中没有为
官方文档参考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 离子含量滚动到底部的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ionic2 中使用 content.scrollTo() 进行离子滚动?