RxJS动态注册事件源和缓冲事件

时间:2017-06-01 11:12:30

标签: javascript angular rxjs

我目前正在尝试使用注册/订阅系统来使用RxJ。

情况是我的组件A有几个子组件A1,A2,A3,......数量必须是动态的。我现在要做的是,每当我将调用“somethingChanged”的事件(已经通过Observable分发)时,所有子组件A1,...将进行一些处理,然后返回一些信息(状态)作为事件我将调用newStates到父动作A可能使用另一个observable。为了使其工作,子组件首先必须将自己注册为“事件管理器”作为A的子项,以便可以相应地处理这些事件。

第一个想法

我的第一个想法是在newStates observable上使用bufferCount,count是注册子组件的数量。问题是子组件注册和订阅newStates observable的父组件几乎同时发生,父组件甚至略快,这意味着amountSub通常为0,这打破了这种尝试。

registerSubComponent() {
  amountSub++;
}

getParentObservable() {
  return newStates.bufferCount(amountSub).mergeMap();
}

第二个想法

第二次尝试是使用somethingChanged事件并使用它来初始化一个takeLast以获取应该抛出它们的最后一项。问题再次出现,因为我会遇到竞争条件,因为子组件需要更长时间才能抛出newStates事件,这意味着我将获得旧值。

registerSubComponent() {
  amountSub++;
}

getParentObservable() {
  return somethingChanged.map(() => newStates.takeLast(amountSub);
}

第三个想法

所以目前我唯一的想法是在事件管理器中捕获newStates事件,将状态存储在一个数组中,并且每次检查所有注册的组件是否通过查看数组长度来发送它们。当所有状态都在我可以然后发送保存的状态并重置阵列。

registerSubComponent() {
  amountSub++;

}

getParentObservable() {
  return newParentObservable;
}

newStates.subscribe(state => {
  savedStates.push(state);
  if(savedStates.length == amountSub) {
    newParentObservable.next(savedStates);
    savedStates = [];
  }
});

这是唯一的方法,还是我错过了一些东西,这样可以更容易/可观察到?

Btw:这是所有伪代码,因为我的实际代码也必须在一个管理器中支持多个父组件,这使得阅读变得很麻烦。

1 个答案:

答案 0 :(得分:0)

听起来你想要对树进行更改检测。使用以下方法和角度服务听起来可能就像你需要的那样:

我在这个家伙Jason Watmore的博客上找到了一个解决方案,该博客描述了使用rxjs Observables和Subjects。使用此方法可以使数据更改轻松地在角度继承树中上下传播到您想要的任何组件

简要说明:

  1. 您在module.ts级别使用3种方法将服务声明为提供者:

    • 的sendMessage
    • clearMessage
    • 的getMessage
    
    
    import { Injectable } from '@angular/core';
     import { Observable } from 'rxjs';
     import { Subject } from 'rxjs/Subject';
    
     @Injectable()
     export class MessageService {
        private subject = new Subject();
    
    
    sendMessage(message: string) {
        this.subject.next({ text: message });
    }
    
    clearMessage() {
        this.subject.next();
    }
    
    getMessage(): Observable<any> {
        return this.subject.asObservable();
    }
    
    }
  2. 此服务需要从rxjs

  3. 导入Observable和Subject
  4. 在您要与之共享数据的每个组件中:

    • 在构造函数中创建一个调用service.getMessage()函数
    • 的订阅对象
    • 在ngOnDestroy中为每个组件调用rxjs subscription.unsubscribe(),这样就不会泄漏内存
    • 您可以挂钩函数来处理传入的订阅更新
  5. 如果您有要与其他组件共享的数据:

    • 创建一个调用service.sendMessage()方法的公共方法
    • 这会将更新的数据发送到每个组件并触发您已连接的功能以处理更改的数据
  6. 我相信我链接的博客帖子和帖子中的plunkr说得最好,并且确实帮助我在我自己的应用程序中有效地移动数据但是如果你有任何问题我会尽力回答它们