#javascript #angular #typescript #socket.io #angular2-template
Вопрос:
это мой первый вопрос на платформе, надеюсь, я все сделаю правильно.
Итак, я работаю в социальной сети, используя MEAN stack и socket.io, и я пытаюсь показать количество непросмотренных уведомлений и сообщений рядом со значками. Все данные обновляются в компоненте с помощью сокетов, и я вижу, что все работает нормально в консоли, данные поступают в режиме реального времени и обновляют массив, длину которого я использую для отображения чисел на панели навигации. Все работает нормально, и он без проблем обновляет номера в представлении, НО когда я изменяю маршрут (даже если я возвращаюсь на тот же URL-адрес), он перестает обновлять представление, независимо от того, какие данные все еще поступают и обновляются в консоли.
Я уже несколько дней занимаюсь этим, провожу исследования, пытаюсь, но не могу заставить это работать. Я пытался:
Использование стратегии определения изменений.OnPush в сочетании с ChangeDetectionRef и его методами, такими как markForCheck, обнаруживает изменения с помощью асинхронного канала.
Попытка повторно отобразить компонент при изменении маршрута не увенчалась успехом.
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);
}
)
}
}
Это шаблон компонента navbar:
<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 amp;amp; 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 amp;amp; 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>
Ответ №1:
Попробуйте отменить подписку на вызовы api, выполняемые в компонентах, в методе ngOnDestroy.