Angular订阅EventEmitter但获取现有项目

问题描述 投票:1回答:1

我正在尝试构建一个通知组件。为此,我需要通过服务向NotificationComponent发送通知。我这样做的方法是使用EventEmitter将通知发送到组件,但是我希望NotificationComponent在第一次通过订阅Observable of Notifications路由到它时获取现有通知,但它不起作用。查看我的代码,请指出问题或建议替代方法。

目前,它仅显示来自通知编号2的通知(这意味着第一个通知没有到达NotificationComponent,但是到达2等等)

以下是NotificationService的代码

import { Injectable } from '@angular/core';
import { Notification } from './notification';
import { from } from 'rxjs';
import { Router } from '@angular/router';
import { EventEmitter } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class NotificationService {
  private notifications = [];
  addEvent = new EventEmitter();
  removeEvent = new EventEmitter();

  constructor(private router: Router) {
  }

  add(title: string, message: string, expiresInSeconds: number = null) {
    const noti = new Notification();
    noti.title = title;
    noti.message = message;
    this.notifications.push();

    this.addEvent.emit(noti);
    this.router.navigate([{ outlets: {notification: 'notification'}}]);

    if (expiresInSeconds > 0) {
      setTimeout(() => {
        this.removeById(noti.id);
      }, expiresInSeconds * 1000);
    }
  }

  /* get notifications */
  getNotifications() {
    return from(this.notifications);
  }

  /* remove a notification */
  removeById(notificationId) {
    const index = this.notifications.findIndex(n => {
      return notificationId === n.id;
    });
    this.notifications.splice(index, 1);

    this.removeEvent.emit(notificationId);
  }

}

以下是NotificationComponent类的代码

import { Component, OnInit } from '@angular/core';
import { NotificationService } from '../notification.service';
import { Notification } from '../notification';
import { faWindowClose } from '@fortawesome/free-solid-svg-icons';
import { Router } from '@angular/router';

@Component({
  selector: 'app-notifications',
  templateUrl: './notifications.component.html',
  styleUrls: ['./notifications.component.scss']
})
export class NotificationsComponent implements OnInit {
  notifications: Notification[] = [];
  faWindowClose = faWindowClose;

  constructor(private ns: NotificationService,
              private router: Router) {
  }

  ngOnInit() {
    this.ns.getNotifications()
      .subscribe(notifications => {
      this.notifications = notifications;
    });

    this.ns.addEvent
      .subscribe((notification => {
        this.notifications.push(notification);
      }));

    this.ns.removeEvent
      .subscribe((notification => {
        const index = this.notifications.findIndex(n => {
          return n.id === notification.id;
        });
        this.notifications.splice(index, 1);
      }));
  }

  removeNotification(id) {
    this.ns.removeById(id);

    if (this.notifications.length <= 0) {
      this.router.navigateByUrl('/user-panel');
    }
  }
}

以下是NotificationComponent的模板html

<div *ngIf="notifications.length >= 1"
  class="notification d-flex flex-row-reverse p-0">
  <div *ngFor="let n of notifications"
    class="alert alert-dark mx-1 p-0">

    <div class="d-flex flex-row p-0">
      <div class="flex-item flex-grow-1">
        <h5>{{n.title}}</h5>
      </div>
      <div class="flex-item">
        <button class="btn btn-sm btn-secondary"
          (click)="removeNotification(n.id)">
          <fa-icon [icon]="faWindowClose"></fa-icon>
        </button>
      </div>
    </div>

    <div>{{n.message}}</div>
  </div>
</div>

我正在尝试构建一个通知组件。为此,我需要通过服务将通知发送到NotificationComponent。我这样做的方法是使用...

angular observable angular-services angular-components eventemitter
1个回答
0
投票

将addEvent转换为ReplaySubject。您的组件在发出第一个通知后呈现,并且仅在第一个事件消失后才预订事件。使用ReplaySubject,您的组件应该会收到第一个事件。

© www.soinside.com 2019 - 2024. All rights reserved.