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();
      });
    });
}