我目前正在为网络应用程序开发一个简单的聊天(如Facebook)。 我正在使用Angular 6作为框架,并使用Firebase作为数据库。
当用户单击某个对话时,我使用select *
from table1 as t1
join table2 as t2
on trim(replace(t2.name, ' ', ' '))
like concat(trim(replace(replace(t1.name, 'A test:', ''), ' ', ' ')), '%') ;
检索以前的消息,然后将结果推入一个数组,该数组将使用.on("child_added, //function here)
循环显示。
我遇到的奇怪问题是消息有时会正确显示,有时根本不会显示。发生这种情况时,只要我单击任意位置,就会再次调用*ngFor
,一切看起来都很好。
我使用*ngFor
发现每次都将数据正确地推入数组,但是由于某种原因,console.logs
(与ngFor
相同)有时会更新,有时只会返回一个空数组。
我的.ts文件(相关部分):
ngAfterViewChecked
模板(相关部分):
ngAfterViewChecked() {
/*
when everything works, this will be called everytime something changes
(even after the array gets populated)
when the issue comes up, this will be called as usual but it won't be called after the array gets populated,
thus returning an empty array the last time it was called
*/
console.log(this.msgService.messageList)
}
//this will be called everytime a user clicks on a conversation on the left sidebar
getSpecConversation(conversation) {
//emptying the array
this.msgService.messageList = [];
//calling the .off using previous conversation key
this.msgService.getConversation(this.msgService.selectedConversation.$key)
.off('child_added');
//getting messages of currently selected conversation
this.msgService.getConversation(conversation.$key)
.on('child_added', (data => {
//push the data into array
this.msgService.messageList.push(data.val());
})
);
//storing currently selected conversation
this.msgService.selectedConversation = conversation;
}
服务:
<ul class="conversation-list">
<li *ngFor="let message of msgService.messageList" class="conversation-item" [class.sender]="message.byUid == userInfoService.userUid">
<p class="message">{{message.msg}}</p>
<p class="msg-time">
<span>{{message.time | date: 'shortTime'}}</span></p>
</li>
</ul>
感谢您的帮助
更新
如果有帮助,如果删除getConversation(sid: string) {
return this.database.ref('/messages')
}
方法,该问题将不再显示,但是,当我发送新消息时,我将在视图中多次调用新消息(不在数据库中)
答案 0 :(得分:0)
更新您的template
并在显示数组之前检查该数组是否包含数据。
<ul class="conversation-list" *ngIf="msgService.messageList && msgService.messageList.length > 0">
<li *ngFor="let message of msgService.messageList" class="conversation-item" [class.sender]="message.byUid == userInfoService.userUid">
<p class="message">{{message.msg}}</p>
<p class="msg-time">
<span>{{message.time | date: 'shortTime'}}</span></p>
</li>
</ul>
这可能是竞争条件-ngFor
循环可以在数组中包含任何数据之前运行,然后在页面上单击时,钩子正在运行,告诉ngFor
运行再次-这次查找数据。
在运行ngIf
之前,它会先检查数据,并在ngFor
可用时立即运行它,该数据现在将遍历并显示在列表中。
答案 1 :(得分:0)
您正在从服务获取数据,因此可能需要使用异步管道。
<li *ngFor="let message of msgService.messageList | async">
<p class="message">{{message.msg}}</p>
</li>