【问题标题】:Why Angular child component ( navbar ) stops updating view after route change?为什么 Angular 子组件 ( navbar ) 在路由更改后停止更新视图?
【发布时间】:2021-05-24 18:11:13
【问题描述】:

这是我在平台上的第一个问题,希望我做对了。

所以,我正在使用 MEAN 堆栈和 socket.io 开发社交网络,并且我试图在图标旁边显示未查看的通知和消息的数量。组件中的所有数据都由套接字更新,我可以看到控制台中的一切工作正常,数据实时到达并更新我用来在导航栏上显示数字的长度的数组。一切正常,它可以毫无问题地更新视图中的数字,但是当我更改路线时(即使我回到相同的 url),它会停止更新视图,无论数据仍在控制台中接收和更新。

我已经被这个问题困扰了好几天,做研究,尝试但我无法让它发挥作用。我试过了:

将 ChangeDetectionStrategy.OnPush 与 ChangeDetectionRef 及其方法如 markForCheck、detectChanges 与异步管道结合使用。

尝试在路由更改时重新渲染组件但没有成功。

ngZone 但老实说我无法理解它。

所以,我正在寻找一些关于正在发生的事情的简短解释以及如何解决它的想法。我知道以前有一些类似的问题,我检查过它们,但无法成功地将它们应用到我的项目中。我希望有人可以帮助我。

这是导航栏组件:

import { Component, OnDestroy, OnInit} from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { UserService } from '../../services/user.service';
import { NotificationService } from '../../services/notification.service';
import { MessageService } from '../../services/message.service';
import { GLOBAL } from '../../services/global';
import { io } from 'socket.io-client';
import { Observable } from 'rxjs';
import { Message } from 'src/app/models/message';

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss'],
  providers: [ MessageService ]
})
export class NavbarComponent implements OnInit{
  private socket = io("ws://localhost:3000");
  public identity;
  public token;
  public url:string;
  public newNotifications$: Observable<boolean>;
  public myNotifications;
  public unviewedMessages: Message[];

  constructor(  public user: UserService,
                private _notificationService: NotificationService,
                private _messageService: MessageService,
                private _route: ActivatedRoute,
                private _router: Router
              ) { 
                this.identity = user.identity;
                this.unviewedMessages = [];
                this.token = user.getToken();
                this.url = GLOBAL.url;
                this.checkIfNewNotifications();
                this.checkUnviewedMessages();
              }
              
  ngOnInit(): void {
    this.sockets()
  }
  
  
  sockets(){
    this.socket.emit("addUser", this.identity._id);
    this.socket.on("newNotification", newNotification =>{
      this.checkIfNewNotifications();
      console.log("nueva notificacion")
    });
    this.socket.on("getMessage", msg =>{
      this.checkUnviewedMessages();
      console.log("nuevo mensaje")
    })   
  }

  logout(){
      localStorage.clear();
      this.identity = null;
      console.log();
      this._router.navigate(['/register']);     
  }

  toTop(event){
    window.scroll(0,0);
  }

  seeNotifications(){
    this.newNotifications$ = new Observable(observer=>observer.next(false));
    this.setViewedNotifications(this.token, this.identity._id);
  }

  checkIfNewNotifications(){
    this._notificationService.getNotifications(this.token).subscribe(
      response => {
        this.myNotifications = response.notifications.filter(notification => notification.viewed == false).length;
        console.log(this.myNotifications)
        if(this.myNotifications > 0){
          this.newNotifications$ = new Observable(observer=>observer.next(true));
        }
      },
      error => {
        console.log(<any>error);
      }
    )
  }

  setViewedNotifications(token, id){
    this._notificationService.setViewedNotifications(token, id).subscribe(
      response =>{
        console.log(response);
      },
      error =>{
        console.log(<any>error);
      }
    )
  }

  checkUnviewedMessages(){
    this._messageService.getUnviewedMessages(this.token).subscribe(
      response => {
        this.unviewedMessages = response.unviewed;
      },
      error => {
        console.log(<any>error);
      }
    )
  }

}

这是导航栏组件模板:

<div class="navigation col-lg-12">
  <nav class="navbar navbar-expand-lg navbar-light bg-light">
    <div class="container-fluid">
      <div class="navbar-header mx-xl-5 mx-lg-5">
        <a [routerLink]="['/timeline']" (click)="toTop($event)" class="navbar-brand">V a p o r b o x</a>
      </div>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
        aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav me-auto mb-2 mb-lg-0">
          <div class="d-flex">
            <li class="nav-item mx-xl-3 mx-lg-3 mobile-avatar">
              <!--Imagen de usuario-->
              <a [routerLink]="['/profile', identity._id]"><img src="{{ url + 'get-image-user/' + identity.image }}"
                  alt="Avatar de usuario logueado" *ngIf="identity && identity.image">
                <img src="../../../assets/img/default-user.jpg" class="default-img" alt="Imagen de usuario"
                  *ngIf="!identity.image || identity.image == null">
              </a>
            </li>
          </div>

          <li class="nav-item mx-xl-3 mx-lg-3">
            <a [routerLink]="['/timeline']" (click)="toTop($event)" class="nav-link">
              <i class="fa fa-home fa-lg mx-lg-2"></i>
              Inicio
            </a>
          </li>

          <li class="nav-item mx-xl-3 mx-lg-3">
            <a [routerLink]="['/users/']" class="nav-link">
              <i class="fa fa-users mx-lg-2"></i>
              Usuarios
            </a>
          </li>

          <li class="nav-item mx-xl-3 mx-lg-3">
            <a [routerLink]="['/chat']" class="nav-link" *ngIf="unviewedMessages">
              <i class="fa fa-comments fa-lg mx-lg-2" *ngIf="unviewedMessages.length < 1"></i>
              <i class="fa fa-comments fa-lg mx-lg-2 new-unviewed" *ngIf="unviewedMessages.length >= 1">
                <small>{{unviewedMessages.length}}</small>
              </i>
              Chat
            </a>
          </li>

          <li id="log-out" class="nav-item mx-xl-3 mx-lg-3">
            <a href="#" (click)="logout()" class="nav-link">
              <i class="fa fa-times fa-lg"></i>
              Cerrar Sesión
            </a>
          </li>
        </ul>
        <ul class="nav navbar navbar-right mx-lg-5" *ngIf="identity">
          <li class="avatar">
            <!--Imagen de usuario-->
            <a [routerLink]="['/profile', identity._id]"><img src="{{ url + 'get-image-user/' + identity.image }}"
                alt="Avatar de usuario logueado" *ngIf="identity && identity.image">
              <img src="../../../assets/img/default-user.jpg" class="default-img" alt="Imagen de usuario"
                *ngIf="!identity.image || identity.image == null"></a>
          </li>
          <li class="dropdown">
            <a class="dropdown-toggle" data-bs-toggle="dropdown" href="#">
              {{identity.name}} <span class="caret"></span>
            </a>
            <ul class="dropdown-menu">
              <li>
                <a [routerLink]="['/profile/'+identity._id]"><i class="fa fa-user mx-2"></i>Perfil</a>
              </li>
              <li>
                <a [routerLink]="['/user-edit']"><i class="fa fa-cog mx-2"></i>Configuración</a>
              </li>
              <li>
                <a href="#" (click)="logout()"><i class="fa fa-times mx-2"></i>Cerrar Sesión</a>
              </li>
            </ul>
          </li>
          <li class="nav-item">
            <a (click)="seeNotifications($event)" [routerLink]="['/notifications']" class="nav-link">
              <i class="fa fa-bell fa-lg" *ngIf="!newNotifications$"></i>
              <i class="fa fa-bell fa-lg new-unviewed" *ngIf="newNotifications$"><small>{{myNotifications}}</small></i>
            </a>
          </li>
        </ul>
      </div>

    </div>
  </nav>
</div>

【问题讨论】:

    标签: javascript angular typescript socket.io angular2-template


    【解决方案1】:

    尝试取消订阅组件中的 api 调用,在 ngOnDestroy 方法中。

    【讨论】:

      猜你喜欢
      • 2018-02-20
      • 2019-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-28
      • 2021-05-19
      • 2023-03-04
      • 1970-01-01
      相关资源
      最近更新 更多