【问题标题】:Angular 2 RxJS check if mouse event is still active after delayAngular 2 RxJS检查延迟后鼠标事件是否仍然有效
【发布时间】:2016-05-20 05:48:45
【问题描述】:

我正在使用 Angular 2 来制定指令。我将以下事件绑定到主机组件:

host: {
    '(mouseenter)': 'onMouseEnter($event)',
    '(mouseleave)': 'onMouseLeave($event)'
}

我还在指令上创建了两个流和侦听器来管理这两个事件

export class PopupDirective {
    private _mouseEnterStream: EventEmitter<any> = new EventEmitter();
    private _mouseLeaveStream: EventEmitter<any> = new EventEmitter();

    onMouseEnter($event) {
         this._mouseEnterStream.emit($event);
    }

    onMouseLeave($event) {
         this._mouseLeaveStream.emit($event);
    }
}

我希望我的subscribe 仅在mouseenter 事件在固定延迟后仍处于活动状态时才被调用(即mouseleave 尚未发生)。我试过这样做,但它不起作用(这是有道理的,我只是不知道如何解决它)。

this._mouseEnterStream.flatMap((e) => {
  return Observable
    .of(e)
    .takeUntil(this._mouseLeaveStream);
}).delay(2000).subscribe(
  () => console.log('yay, it worked!')
);

有 Angular 2 / RxJS 经验的人知道我应该如何处理这个问题吗?

【问题讨论】:

  • this._mouseStream 来自哪里?
  • @GünterZöchbauer 抱歉,应该是 mouseEnterStream
  • 顺便说一句,因为你使用的是 Rx,所以你真的不需要 EventEmitters。只需使用主题即可。有点惊讶您可以将 EventEmitters 用作 Observables,也许 ng2 会在后台转换它们。
  • @kakigoori EventEmitters Observables的重点不是吗?不过感谢您的提示。
  • 通常要在其他项目中将 EventEmitters 用于 Observables,您必须使用静态 fromEvent 方法从事件发射器生成一个 observable。我曾经是事件发射器的重度用户,但是冷/热流、操作符和整个创建/订阅/处置都太好了。 (你可能会发现 Andre 的帖子很有用:stackoverflow.com/questions/25338930/…

标签: angular rxjs rxjs5


【解决方案1】:

Günter 的答案正是您所期望的,但您应该使用 of 运算符而不是 return 运算符。

this._mouseEnterStream.flatMap((e) => {
  console.log('_mouseEnterStream.flatMap');
  return Observable
      .of(e)
      .delay(2000)
      .takeUntil(this._mouseLeaveStream);
}).subscribe(
  (e) => {
    console.log('yay, it worked!');
    console.log(e);
  }
);

查看对应的plunkr:https://plnkr.co/edit/vP3xRDXxFanqzLEKd3eo?p=preview

另外,a proposal in Angular 旨在简化使用 Rx 通过模板语法从 DOM 事件创建可观察对象的方式。

【讨论】:

  • 如果它只是一个你想返回的值,.just 更有意义。但对于非 Haskelly 语言的用户来说,这可能是胡言乱语。
  • 感谢您的评论,但 Rxjs 5.0.0-beta.0 不存在此运算符。看到这个错误:Rx_1.Observable.just is not a function
  • 哦,抱歉,看起来它已在 RxJS5 beta 的迁移文档中列出。不过有点难过。
  • 不知道为什么.subscribe 需要连接到.flatMap 才能工作,但这是完美的!谢谢。
  • 只是创建数据流。当接收到第一个事件时,它将被映射到另一个处理延迟的链......
【解决方案2】:

看起来和How do I timeout an event in RxJS?很相似

this.myStream = this._mouseEnterStream
    .flatMap((e) => {
        return Observable
            .of(e)
            .delay(2000)
            .takeUntil(mouseLeaveStream);
    });

myStream.subscribe((x) => { 
        console.log('onNext: ', x);
});

我自己不使用 TS 或 Rx(只有 Dart),因此我不知道这是否是正确的语法,或者运算符的名称是否与 Angular 可用的这些匹配。

【讨论】:

  • 有趣的是,我在发布这篇文章之前就尝试了这个选项——但出于某种原因,需要将 .susbcribe 连接到 .flatMap 以使其工作——否则“next”会在 mouseenter 事件上立即触发。
猜你喜欢
  • 2016-04-18
  • 1970-01-01
  • 2021-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-29
  • 1970-01-01
相关资源
最近更新 更多