Rxjs 鼠标悬停通知流,鼠标悬停恢复

Rxjs 鼠标悬停通知流,鼠标悬停恢复,rxjs,rxjs6,Rxjs,Rxjs6,我有一个显示/隐藏通知的流: this.subscription = this.notificationsApi.notifications$.pipe( concatMap((event) => { return of(event).pipe( delay(450), tap(() => { this.notification = event; this.isActive = true; this

我有一个显示/隐藏通知的流:

this.subscription = this.notificationsApi.notifications$.pipe(
  concatMap((event) => {

    return of(event).pipe(
      delay(450),
      tap(() => {
        this.notification = event;
        this.isActive = true;
        this.cd.markForCheck();
      }),
      delay(isDefined(event.showFor) ? event.showFor : this.hideAfter),
      /// Pause here if you hover over the notification ///
      tap(() => {
        this.isActive = false;
        this.cd.markForCheck();
      }),
      delay(450)
    );
  })
).subscribe(() => {});
我想做的是当您将鼠标悬停在通知上时暂停流,当您不再将鼠标悬停在通知上时继续:

<div (mouseover)="pause()" (mouseout)="continue()"></div>

在这种情况下,我似乎找不到有效的解决方案。我假设我必须使用另一个1-2
Subject
s,然后使用
switchMap
,这取决于你是暂停还是继续,但就像我说的,我不知道具体怎么做

我试着看,但当我尝试这种方法时,它根本没有显示任何通知

有指针吗?

检查并

主要的诀窍是至少等一等

  • 通知显示延迟
  • 以及流上的下一条消息
让鼠标进出增加延迟

concatMap
中的魔法实现了这一点(至少,我认为它实现了…)

要开始,我们需要
通知$
并在其上设置一个延迟。因此,每个消息将至少显示
延迟
时间

注:伪代码

notifications$.concatMap(msg=>
定时器(延迟)
.ignoreElements()
.startWith(msg)
)
然后我们希望鼠标延迟延迟

通知$
.concatMap(msg=>
老鼠$
.switchMap(isOver=>{/<我们延迟鼠标状态更改
如果(isOver){
返回空()
}
返回计时器(延迟);//<延迟后--接收下一个MSG
})
//我们只需要此鼠标$+流中的一个完成事件
.采取(1)
//将延迟流转换为具有延迟的消息流的现有逻辑
.ignoreElements()
.startWith(msg)
)
最后,如果在延迟之后出现下一条消息——我们仍然需要听到鼠标悬停并通过它们进行延迟

//存储当前消息索引
让currentMsgIndex=-1;
通知$
//存储当前消息索引
.map((msg,i)=>{
currentMsgIndex=i;
返回味精;
})
.concatMap((msg,i)=>{
//我们通过鼠标收听事件
返回内存鼠标$
//如果鼠标位置已更改--恢复超时
.switchMap(值=>{
//不要在老鼠身上做任何事
如果(值){
返回空();
}
//直到下一条消息出现——我们正在跟踪鼠标进出
让我们等待美元;
如果(i==currentMsgIndex){
//当前消息是最新的
nextMsgAwait$=notifications$.pipe(取(1));
}否则{
//我们已经有下一个MSG要展示了
nextMsgAwait$=的(无效0);
}
//如果老鼠不在——等待
//-超时计时器
//-直到新消息到达
//在此之前,用户可以使用鼠标进出
//延迟下一个消息显示
返回叉连接(
计时器(超时)
,下一个,等等$
);
}),
//我们只需要此鼠标$+流中的一个完成事件
.采取(1)
//将延迟流转换为具有延迟的消息流的现有逻辑
.ignoreElements()
.startWith(msg)
})

为了更好地理解,请参阅上面提到的示例——我在这里添加了一些注释。

您是否尝试创建
isHover
标志并添加
过滤器()=>!isHover
在延迟和点击之间?@PrzemyslawPietrzak不,感觉这会取消流而不是暂停流。但是过滤后的可观察数据仍然存在,只有滴答声被忽略。这样做比被动方式更为必要,但我没有更好的主意。您尝试过使用CombineRelatest吗?这个rxjs操作符将允许您获取com从多个流中,你可以有两个流:mouseover和notification,通过组合这两个流,你可以设置一个过滤器,并且只有当鼠标移到FalseCombineTest时才继续。imho,不会这样做:用户可能永远不会悬停通知,或者在延迟期间将它们悬停几次。我会在有时间的时候尝试这个方法!我不能说我理解什么不会发生,但只要它起作用,我真的不在乎:)回答得好@Chrillewoodz我也不能断言:)虽然,在写了它之后,评论、解释并再次重写了cz的bug+使用了一系列工具来探索线程。此外,您还必须支持和扩展它。所以我想:也许写这些东西时不使用反应式代码会更好,但是使用好的旧命令式代码和一堆设置超时和标志?不确定。你觉得呢?我以前试过这种方法,但要让一个非队列版本在没有超时的情况下工作真的很难。我认为反应式方法是正确的。@Chrillewoodz,我一直在写一篇文章,并重新讨论了这个例子。我在实现中犯了一个错误:即使鼠标悬停,某些消息也可能会滑到视图中。我现在已经修复了这个问题,并将stackblitz与游乐场示例一起更新。很抱歉