等待多个事件,然后执行一个方法

时间:2017-08-22 13:33:28

标签: angular dom observable

我正在Angular 4中创建一个聊天应用程序。

我需要在3个条件成立后执行方法(markMessageAsRead)(Chrome标签处于活动状态,侧边栏已打开且侧边栏标签为“聊天”)。

订阅每个单独的功能将无法解决此问题,因为当1个条件发生变化时,您必须再次检查其他2个条件。

我无法找到等待所有这三个条件成立的解决方案。 有什么想法吗?

  • 我可以在document.hasFocus()中添加一个eventlistener来监视更改。
  • 其他两个条件是我可以订阅的BehaviorSubjects,以观察更改。

2 个答案:

答案 0 :(得分:3)

我会使用Observable.zip运算符:

About zip operator

首先需要做的是使用observable将焦点事件转换为Observable.fromEvent,然后使用zip运算符和filter,如下所示:

Observable.zip(Observable.fromEvent(focusEvent),
               behaviourSubjectOne.asObservable(),
               behaviourSubjectTwo.asObservable())
  .filter((arrayOfResults) => !arrayOfResults.some((val) => val === false))
  .subscribe(() => {
      // all three conditions are fulfilled, do what you need here
  });

修改

经过一些修改后,我来到了这里:

https://plnkr.co/edit/spNldiSb1WwgmrHrB6u1

如果plunker丢失,则发布代码(省略HTML):

export class App {
  name:string;
  output: string = '';

  subjectOne: BehaviorSubject <boolean> = new BehaviorSubject <boolean>(false);
  subjectTwo: BehaviorSubject <boolean> = new BehaviorSubject <boolean>(false);

  constructor() {
    this.name = `Angular! v${VERSION.full}`;
    Observable.combineLatest(Observable.merge(Observable.fromEvent(window, 'focus').map((ev) => 'focus'),
                   Observable.fromEvent(window, 'blur').map((ev) => 'blur')).startWith('blur'),
                   this.subjectOne.asObservable(),
                   this.subjectTwo.asObservable())
              .map((state) => [state[0] === 'focus', state[1], state[2]])
              // filter would go here
              .subscribe((array) => {
                this.output = JSON.stringify(array);
              });
  }
}

这是一个复杂的可观察链,但我会尝试解释我做了什么:

首先,我使用了combineLatest运算符来监听三个布尔值的状态变化。作为第一个参数,我传递了焦点和模糊事件的合并observable。由于一次只能触发一个,因此总是给出窗口的当前状态。 StartWith用于初始状态。然后受试者被传入。

然后我将它映射到OP可以应用上述过滤器的数组。

答案 1 :(得分:0)

你问过我是否使用了BehaviourSubject和Observable。 对于该信息,我建议您阅读以下引用:

  

BehaviorSubject是一种主题,主题是一种特殊类型   可观察,因此您可以订阅任何其他可观察的消息。   BehaviorSubject的独特功能是:

     
      
  • 它需要一个初始值,因为它必须始终返回订阅值,即使它没有收到next()
  •   
  • 订阅后,它会返回主题的最后一个值。常规observable仅在收到onnext
  • 时触发   
  • 您可以使用getValue()方法在任何时候检索不可观察代码中主题的最后一个值。
  •   
     

与可观察对象相比,主题的独特特征是:

     
      
  • 除了作为观察者之外,它还是一个观察者,因此除了订阅它之外,您还可以向主题发送值。
  •   
     

此外,您可以使用以下方式从行为主题中获取可观察量   BehaviorSubject上的asobservable()方法。

取自: BehaviorSubject vs Observable?

阅读之后,您应该能够回答自己的问题。

您的问题

必须&#34;观看3个值&#34; (你自己),你只需要观看1.这是由于布尔运作的方式。

e.g

$scope.something = $scope.first && $scope.second && $scope.third

这可以产生几个结果:

| First     | Second    | Third     | Result    |
|-------    |--------   |-------    |--------   |
| True      | True      | True      | True      |
| True      | False     | False     | False     |
| False     | True      | False     | False     |
| False     | False     | True      | False     |
| False     | False     | False     | False     |

所以我个人所做的只是观看单一价值,即所有3的组合。

你完全关注变量的新问题

一旦达到条件,您可以使用subscribeto激活事件:

.subscribe(() => {
    DoFuctionCall();
})

再次阅读引用(和那个问题)来弄清楚:D