Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript RxJS动态注册事件源和缓冲区事件_Javascript_Angular_Rxjs - Fatal编程技术网

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

Javascript RxJS动态注册事件源和缓冲区事件,javascript,angular,rxjs,Javascript,Angular,Rxjs,我目前正在尝试让注册/订阅系统与RxJs一起工作 情况是,我有组件A和几个子组件A1,A2,A3。。。数量必须是动态的。我现在想做的是,每当一个我称之为“somethingChanged”的事件发生时(它已经通过一个可观察对象分布),所有子组件A1。。。将执行一些处理,然后作为事件返回一些信息(状态),我将调用newStates到父操作a,可能使用另一个可观察的对象。为了实现这一点,子组件首先必须将自己注册到“事件管理器”中,作为事件的子组件,以便相应地处理这些事件 第一个想法 我的第一个想法是

我目前正在尝试让注册/订阅系统与RxJs一起工作

情况是,我有组件A和几个子组件A1,A2,A3。。。数量必须是动态的。我现在想做的是,每当一个我称之为“somethingChanged”的事件发生时(它已经通过一个可观察对象分布),所有子组件A1。。。将执行一些处理,然后作为事件返回一些信息(状态),我将调用newStates到父操作a,可能使用另一个可观察的对象。为了实现这一点,子组件首先必须将自己注册到“事件管理器”中,作为事件的子组件,以便相应地处理这些事件

第一个想法 我的第一个想法是对可观察的newStates使用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 = [];
  }
});
这是唯一的方法吗?还是我遗漏了一些东西,因此可以更容易地/通过观察来完成


顺便说一句:这都是伪代码,因为我的实际代码还必须在一个管理器中支持多个父组件,这使得通读起来很麻烦。

听起来您希望在树上进行更改检测。对角度服务使用以下方法听起来可能是您所需要的:

我在Jason Watmore的博客上找到了一个解决方案,它描述了如何使用rxjs观测值和主题。使用此方法,数据更改可以轻松地在角度继承树上下传播到所需的任何组件

简要说明:

  • 使用3种方法在module.ts级别将服务声明为提供程序:

    • 发送消息
    • 清晰信息
    • 获取消息
    从“@angular/core”导入{Injectable}; 从“rxjs”导入{Observable}; 从'rxjs/Subject'导入{Subject}; @可注射() 导出类消息服务{ 私有主体=新主体();
    sendMessage(消息:字符串){
    this.subject.next({text:message});
    }
    clearMessage(){
    this.subject.next();
    }
    getMessage():可观察{
    返回此.subject.asObservable();
    }
    
    }
  • 此服务需要从rxjs导入可观察和主题

  • 在要与之共享数据的每个组件中:

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

    • 创建一个调用service.sendMessage()方法的公共方法
    • 这会将更新的数据发送到每个组件,并启动那些您已连接的函数来处理更改的数据

  • 我相信我链接到的博客帖子和帖子中的plunkr说得最好,并且确实帮助我在自己的应用程序中高效地移动数据,但是如果你有任何问题,我会尽力回答你的问题

    我还不确定你想做什么,但它提醒了我Cycle.js是如何处理收集的。我可能错了,但也许浏览一下可以给你一些想法:)
    a
    组件是否负责实例化
    A1
    A2
    。。。?它们是具有不同数据的同一个组件,还是完全不同的组件?基本上,
    cycle.js
    的思想是,组件是一个函数,它接受一些输入流(在您的情况下,我认为是
    somethingcound
    事件),并返回一些其他流(在您的情况下,是您希望它们产生的状态)从cycle.js的简要介绍来看,它似乎也只是帮助您将事件发送给家长,类似于Jake的回答,但我对此没有问题。我遇到的问题是聚合任何somethingChanged事件之后发生的所有事件,并将此“缓冲区”返回给父级。另外,我觉得将cycle.js引入angular 4并不容易,因为angular尽可能避免直接访问javascript/typescript代码中的dom元素。谢谢你的输入。谢谢你的回答,但是我已经知道这个技巧,并且已经使用过好几次了。链接帖子中提到的实现和写入只考虑一个子组件向父节点发送一个事件。我的情况基于此设计,但在每个somethingChanged事件之后尝试聚合子组件中的所有事件,并将其返回给父组件。 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();
    }