Angular 中带有 rxjs 的用户通知服务? [英] User notification service with rxjs in Angular?

查看:38
本文介绍了Angular 中带有 rxjs 的用户通知服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对响应式编程比较陌生,我正在尝试创建一个可以向用户显示通知的 Angular 服务.到目前为止,这就是我所拥有的:

I'm relatively new to reactive programming and I'm trying to create an Angular service which can display notifications to the user. So far this is what I have:

https://stackblitz.com/edit/angular-rxjs-notifications?file=app%2Fapp.component.html

但是我的实现存在一个主要问题,我不知道如何解决:如何以反应式方式将通知排队?我希望我的通知 div 在推送第一个通知时出现,当用户单击清除"时,我希望 div 消失,除非此后推送了其他通知.这样 clear 会显示下一个通知,依此类推,直到所有通知都被清除.然后,只要推送新通知,div 就会再次弹出.

But there is a major problem with my implementation that I don't know how to solve: How, in a reactive way, can I queue up notifications? I would like my notification div to appear when the first notification is pushed and when the user clicks "Clear" I would like the div to disappear unless other notifications have been pushed since. That way clear would show the next notification and so on until all notifications have been cleared. Then as soon as a new notification is pushed the div should pop up again.

我在实现中选择了 Subject 而不是 ReplaySubject,因为我不希望用户看到在加载下一个屏幕时推送的通知,但我意识到如果我在我的 app.component.html 中使用路由器,那么无论如何我都会遇到这种行为.也许我需要在路由发生时清除通知队列?

I chose a Subject in my implementation over a ReplaySubject because I don't want users to see notifications that were pushed while they were loading the next screen but I realized that if I'm using a router inside my app.component.html then I'll run into that behavior anyways. Maybe I need to clear the notification queue when a routing occurs?

提前致谢!

推荐答案

示例服务可以是这样的

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { merge } from 'rxjs/observable/merge';
import { map, scan } from 'rxjs/operators';

enum ActionType {
  push = 'push',
  pop = 'pop'
}

interface Action {
  type: ActionType;
}

interface PushAction extends Action {
  payload: string;
}

interface PopAction extends Action { }

@Injectable()
export class NotificationService {
  messages$: Observable<string[]>;

  private pushSource = new Subject<string>();
  private popSource = new Subject<void>();

  constructor() {
    const push$ = this.pushSource.asObservable()
      .pipe(map((payload) => ({ type: ActionType.push, payload })));

    const pop$ = this.popSource.asObservable()
      .pipe(map((payload) => ({ type: ActionType.pop })));

    this.messages$ = merge(push$, pop$)
      .pipe(
      scan((acc: any, { payload, type }) => {
        if (type === ActionType.pop) {
          acc = acc.slice(0, -1);
        }
        if (type === ActionType.push) {
          acc = [...acc, payload]
        }
        return acc;
      }, [])
      )
  }

  pushMessage(msg: string) {
    this.pushSource.next(msg)
  }

  popMessage() {
    this.popSource.next()
  }
}

现场演示

我们有两个流,pop$push$ 我们合并在一起.我们然后使用 scan 运算符将其缩减为单个数组.

We have two streams, pop$ and push$ that we merge together. We than reduce it into a single array using the scan operator.

所以一个流push(hello) ->推(世界)->流行音乐 ->push(kitty) 将简化为 [hello, kitty].

So a stream of push(hello) -> push(world) -> pop -> push(kitty) would be reduced to [hello, kitty].

这篇关于Angular 中带有 rxjs 的用户通知服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆