rxjs ReplaySubject handle - PullRequest
0 голосов
/ 05 июля 2018

У меня проблема с шаблоном, который я использую в angular 4. Этот шаблон реализует систему уведомлений, где вы можете добавлять новые уведомления, но в документации не указано, как можно удалять элементы обозревателя ReplaySubject.

Шаблон реализует это как сервис следующим образом:

private notificationsList: Notification[] = [];
  // a stream that publishes new notifications only once
  public newNotifications: Subject<Notification> = new Subject<Notification>();

  // `notifications` is a stream that emits an array of the most up to date notifications
  public notifications: ReplaySubject<Notification[]> =
      new ReplaySubject<Notification[]>(1);

  // `updates` receives _operations_ to be applied to our `notifications`
  // it's a way we can perform changes on *all* notifications (that are currently
  // stored in `notifications`)
  public updates: Subject<any> = new Subject<any>();

  // action streams
  public create: Subject<Notification> = new Subject<Notification>();
  // public markThreadAsRead: Subject<any> = new Subject<any>();

  constructor() {
    // recois des operation, et les fais sur la liste interne, puis diffuse le
    // resultat sur notifications
    this.updates.subscribe((ope) => {
      this.notificationsList = ope(this.notificationsList);
      console.log(this.notificationsList);
      this.notifications.next(this.notificationsList);
    });

    this.newNotifications
      .map(function(notification: Notification): INotificationsOperation {
        return (notifications: Notification[]) => {
          return notifications.concat(notification);
        };
      })
      .subscribe(this.updates);

  }

  // an imperative function call to this action stream
  public addNotification(notification: Notification): void {
    this.newNotifications.next(notification);
  }

Я пытаюсь спросить владельца, как я могу удалить фактический элемент списка уведомлений, но он просто говорит мне, что я могу получить доступ к теме "уведомлений", чтобы получить его последнюю версию. Но не упоминайте, как я могу на самом деле удалить элемент списка.

Кто-нибудь что-то знает?

Спасибо!

1 Ответ

0 голосов
/ 06 июля 2018

Я добавил публичную функцию, которую вы можете использовать. Я добавил комментарий, чтобы вы могли видеть, какую часть кода вы можете изменить, например, если вы хотите удалить элементы по имени или не хотите изменять размер списка. Пояснение в конце моего поста.

  private notificationsList: Notification[] = [];
  // a stream that publishes new notifications only once
  public newNotifications: Subject<Notification> = new Subject<Notification>();
  public removeNotificationByIndex$ : Subject<number> = new Subject<number>();
  // `notifications` is a stream that emits an array of the most up to date notifications
  public notifications: ReplaySubject<Notification[]> =
      new ReplaySubject<Notification[]>(1);

  // `updates` receives _operations_ to be applied to our `notifications`
  // it's a way we can perform changes on *all* notifications (that are currently
  // stored in `notifications`)
  public updates: Subject<any> = new Subject<any>();

  // action streams
  public create: Subject<Notification> = new Subject<Notification>();
  // public markThreadAsRead: Subject<any> = new Subject<any>();

  constructor() {
    // recois des operation, et les fais sur la liste interne, puis diffuse le
    // resultat sur notifications
    this.updates.subscribe((ope) => {
      this.notificationsList = ope(this.notificationsList);
      console.log(this.notificationsList);
      this.notifications.next(this.notificationsList);
    });

    this.newNotifications
      .map(function(notification: Notification): INotificationsOperation {
        return (notifications: Notification[]) => {
          return notifications.concat(notification);
        };
      })
      .subscribe(this.updates);

    this.removeNotificationByIndex$
     .map(function(index: number){
        return (notifications: Notification[]) => {
        // >>>> DELETE METHOD IS TO BE DEFINED DOWN HERE !
        notifications.splice(index,1);
        // >>>> DELETE METHOD IS TO BE DEFINED UP HERE !
      return notifications
     };
     })
     .subscribe(this.updates);

  }

  // an imperative function call to this action stream
  public addNotification(notification: Notification): void {
    this.newNotifications.next(notification);
  }

  // delete the element in the "index" position of the list. 
  // /!\ Resizes the list 
  public removeNotificationsByIndex(index: number): void {
    this.removeNotificationByIndex$.next(index);
  }

Какие изменения?

public removeNotificationByIndex$ : Subject<number> = new Subject<number>();

Этот субъект получит (асинхронно) индекс и запустит процесс, используя этот индекс.

 this.removeNotificationByIndex$
 .map(function(index: number){
    return (notifications: Notification[]) => {
    // >>>> DELETE METHOD IS TO BE DEFINED DOWN HERE !
    notifications.splice(index,1);
    // >>>> DELETE METHOD IS TO BE DEFINED UP HERE !
  return notifications
 };
 })
 .subscribe(this.updates);

Когда создается индекс (т.е. вы используете связанную императивную функцию), из него генерируется функция (функция стрелки ES6). Вот оно:

(notifications: Notification[]) => {
    // >>>> DELETE METHOD IS TO BE DEFINED DOWN HERE !
    notifications.splice(index,1);
    // >>>> DELETE METHOD IS TO BE DEFINED UP HERE !
  return notifications
 };

Эта функция передается this.update, которая будет применять ее. В этом контексте ope является этой функцией. при получении this.notificationList изменяется следующим образом:

this.notificationsList = ope(this.notificationsList);

Наконец, этот новый список публикуется в ReplaySubject notifications:

this.notifications.next(this.notificationsList);

Которые распространяют этот новый список всем своим подписчикам.

Вуаля :). Удачи!

...