Ngfor 没有在重新加载页面上实现(Angular + RXJS)
Ngfor doesn't actualize on reloading page (Angular + RXJS)
你好,我正在用 angular 为一个学校项目构建一个聊天应用程序,我正在使用 firebase 作为我的后端,我的 ngfor 有问题。
例如,如果我重新加载页面,我什么也看不到,除非我将我的路由器链接悬停在我的导航栏上。但是有时它会在页面上运行一段时间后无需任何操作
当我收到消息时,我需要在页面上才能看到它们...
当我第一次重新加载我的页面时,我的数组是空的,这可能是导致 ngfor 错误的原因
array on reload.
我正在使用 ngOnInit() 进行订阅:
messages: Message[];
messageSubscription: Subscription;
constructor(private messageService: MessageService, private router: Router) {
}
ngOnInit(): void {
this.messageSubscription = this.messageService.messageSubject.subscribe(
(messages: Message[]) => {
console.log(messages)
this.messages = messages;
}
);
this.messageService.getMessage();
this.messageService.emitMessage();
}
ngOnDestroy(): void {
this.messageSubscription.unsubscribe();
}
这是我的 html 模板:
<div *ngFor="let message of messages" class="message-box">
<img [src]="message.photoURL" class="profile-picture">
<div class="content-box">
<div class="information">
<p class="username">{{message.displayName}}</p>
<p class="date">{{message.createdAt | date: 'short'}}</p>
</div>
<p class="text">{{message.text}}</p>
</div>
</div>
在这里您可以使用我的 getMessage() 函数和 emitMessage() 找到我的服务:
messages:Message[] = [];
messageSubject = new Subject<Message[]>();
constructor() { }
emitMessage(){
this.messageSubject.next(this.messages);
}
saveMessage(newMessage: Message){
firebase.database().ref('/message').push(newMessage);
}
getMessage(){
firebase.database().ref('/message')
.on('value', (data) => {
this.messages = data.val() ? Object.values(data.val()): [];
this.emitMessage();
});
}
这是我项目的仓库:https://github.com/Zuxaw/AngularChatApp
如果有人有我感兴趣的解决方案
我认为您可能需要在 getMessage
方法中使用 child_added
事件而不是 value
。
检查您是否在 getMessage
方法中按时接收数据,如果不是,很可能是因为事件。
但是我不明白的一件事是为什么你在 getMessage
中调用 emitMessage
并在 getMessage
之后在你的组件中调用它,尽量避免这种情况。
问题是,您的 firebase 库不是 Angular 特定的。
这意味着您有时需要确保它的代码,主要是它的事件回调,运行 在 Angular 区域内(google 阅读它)以确保数据更改时调用更改检测 'tick'。
message.service.ts
import { Injectable, NgZone } from '@angular/core';
// ...
constructor(private zone: NgZone) { }
// ..
getMessage(){
firebase.database().ref('/message')
.on('value', (data) => {
this.zone.run(() => {
this.messages = data.val() ? Object.values(data.val()): [];
this.emitMessage();
});
});
}
你好,我正在用 angular 为一个学校项目构建一个聊天应用程序,我正在使用 firebase 作为我的后端,我的 ngfor 有问题。
例如,如果我重新加载页面,我什么也看不到,除非我将我的路由器链接悬停在我的导航栏上。但是有时它会在页面上运行一段时间后无需任何操作
当我收到消息时,我需要在页面上才能看到它们...
当我第一次重新加载我的页面时,我的数组是空的,这可能是导致 ngfor 错误的原因 array on reload.
我正在使用 ngOnInit() 进行订阅:
messages: Message[];
messageSubscription: Subscription;
constructor(private messageService: MessageService, private router: Router) {
}
ngOnInit(): void {
this.messageSubscription = this.messageService.messageSubject.subscribe(
(messages: Message[]) => {
console.log(messages)
this.messages = messages;
}
);
this.messageService.getMessage();
this.messageService.emitMessage();
}
ngOnDestroy(): void {
this.messageSubscription.unsubscribe();
}
这是我的 html 模板:
<div *ngFor="let message of messages" class="message-box">
<img [src]="message.photoURL" class="profile-picture">
<div class="content-box">
<div class="information">
<p class="username">{{message.displayName}}</p>
<p class="date">{{message.createdAt | date: 'short'}}</p>
</div>
<p class="text">{{message.text}}</p>
</div>
</div>
在这里您可以使用我的 getMessage() 函数和 emitMessage() 找到我的服务:
messages:Message[] = [];
messageSubject = new Subject<Message[]>();
constructor() { }
emitMessage(){
this.messageSubject.next(this.messages);
}
saveMessage(newMessage: Message){
firebase.database().ref('/message').push(newMessage);
}
getMessage(){
firebase.database().ref('/message')
.on('value', (data) => {
this.messages = data.val() ? Object.values(data.val()): [];
this.emitMessage();
});
}
这是我项目的仓库:https://github.com/Zuxaw/AngularChatApp
如果有人有我感兴趣的解决方案
我认为您可能需要在 getMessage
方法中使用 child_added
事件而不是 value
。
检查您是否在 getMessage
方法中按时接收数据,如果不是,很可能是因为事件。
但是我不明白的一件事是为什么你在 getMessage
中调用 emitMessage
并在 getMessage
之后在你的组件中调用它,尽量避免这种情况。
问题是,您的 firebase 库不是 Angular 特定的。
这意味着您有时需要确保它的代码,主要是它的事件回调,运行 在 Angular 区域内(google 阅读它)以确保数据更改时调用更改检测 'tick'。
message.service.ts
import { Injectable, NgZone } from '@angular/core';
// ...
constructor(private zone: NgZone) { }
// ..
getMessage(){
firebase.database().ref('/message')
.on('value', (data) => {
this.zone.run(() => {
this.messages = data.val() ? Object.values(data.val()): [];
this.emitMessage();
});
});
}