我正在尝试使用Ionic 3和Firebase创建一个简单的聊天应用程序。注册,登录用户,发送和显示其消息的工作。这是所有用户的常见聊天室。
当用户被登录或登录以让其他用户知道时,我希望一条消息出现在聊天室中。登录测试用户时,此消息将显示:"加入了房间"
登录测试用户时,会出现此消息:" test@gmail.com已离开房间"
我希望用户名(电子邮件地址)显示何时登录用户。我希望此消息出现:" test@gmail.com加入了房间"
我尝试在控制台上写下此。username,但它仅将其写入控制台:ionviewDidload chatpage。用户名不会出现在控制台上:console.log('ionviewDidload chatpage',this.username);
chat.ts:
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { AngularFireDatabase, AngularFireObject } from 'angularfire2/database';
import { Storage } from '@ionic/storage';
import { Subscription } from 'rxjs/Subscription';
import $ from 'jquery';
@IonicPage()
@Component({
selector: 'page-chat',
templateUrl: 'chat.html',
})
export class ChatPage {
username: string= '';
message: string= '';
obsRef: AngularFireObject<any>;
obsToData: Subscription;
messages: object[]= [];
constructor(public db: AngularFireDatabase, public navCtrl: NavController, public navParams: NavParams, private storage: Storage) {
this.storage.get('username').then((val) => {
if (val != null) {
this.username= val;
}
});
this.obsRef = this.db.object('/chat');
this.obsToData = this.obsRef.valueChanges().subscribe( data => {
var data_array= $.map(data, function(value, index) {
return [value];
});
this.messages= data_array;
});
}
sendMessage() {
this.db.list('/chat').push({
username: this.username,
message: this.message
}).then( () => {
this.message= '';
});
}
ionViewWillLeave() {
console.log('user is about to go');
this.obsToData.unsubscribe();
this.db.list('/chat').push({
specialMessage: true,
message: this.username + `has joined the room`
})
}
ionViewDidLoad() {
console.log('ionViewDidLoad ChatPage', this.username);
this.db.list('/chat').push({
specialMessage: true,
message: this.username + `has joined the room`
})
}
}
chat.html:
<ion-header>
<ion-navbar>
<ion-title>Chat</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<div id="chatMessages">
<div *ngFor="let message of messages" [class]="message.specialMessage ? 'message special': 'message'">
<div [class]="message.username == username ? 'innerMessage messageRight': 'innerMessage messageLeft'">
<div class="username"> {{ message.username }} </div>
<div class="messageContent"> {{ message.message }} </div>
</div>
</div>
</div>
</ion-content>
<ion-footer>
<div id="footer">
<ion-input type="text" [(ngModel)]= "message"> </ion-input>
<button ion-button icon-only (click)= "sendMessage()">
<ion-icon name="send"></ion-icon>
</button>
</div>
</ion-footer>
查看您的代码,您正在从存储中获取用户名。这是一个异步操作,这意味着它可以在IonViewLoad事件发生之前或之后发生。这意味着以下几行
this.storage.get('username').then((val) => {
if (val != null) { // this will run later
this.username= val;
}
构造函数将存在,而没有任何"然后"中的任何内容。每当存储准备好结果时,这些线将在以后运行。
将其视为订购数据订单。仅仅因为您已下达订单,并不意味着您的订单已经到了。
看起来,当您离开视图时,呼叫的呼叫已经完成,并且设置了用户名。
我建议您以某种方式等待用户名像
一样到达<div id="chatMessages" *ngIf="username?.length > 0">
,甚至更好的是,对代码进行重构,以便在获得此视图时准备好用户名。毕竟,如果没有准备好用户名,这些观点是无法使用的。
我怀疑您正在使用标签布局。如果是这种情况,请尝试使用ionViewDidEnter()
获取存储的结果,以便每次输入页面时,结果都会更新。尝试做这样的事情并检查
ionViewDidEnter(){
this.storage.get('username').then((val) => {
if (val != null) {
this.username= val;
}
});
}