Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.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
在typescript中观察集合_Typescript_Rxjs_Observable_System.reactive - Fatal编程技术网

在typescript中观察集合

在typescript中观察集合,typescript,rxjs,observable,system.reactive,Typescript,Rxjs,Observable,System.reactive,我在typescript中使用RxJS,希望有一种通用的方法来处理集合中的更改。一个非常幼稚的实现类似于 Observable<Element[]> 在这种情况下,我希望在添加、删除或修改任何元素时收到通知(如果id保持不变,则元素被视为已修改,但某些属性没有) 在这种情况下,我需要某种额外的可观察管道操作来接收集合,并基于存储的(以前的)值生成一个CollectionChangedEvent,它具有一个类型(即添加的,删除的,修改的)和一个id(目标元素)。基于每个元素的哈希计算

我在typescript中使用RxJS,希望有一种通用的方法来处理集合中的更改。一个非常幼稚的实现类似于

Observable<Element[]>
在这种情况下,我希望在添加、删除或修改任何元素时收到通知(如果
id
保持不变,则元素被视为已修改,但某些属性没有)

在这种情况下,我需要某种额外的可观察管道操作来接收集合,并基于存储的(以前的)值生成一个
CollectionChangedEvent
,它具有一个类型(即添加的
删除的
修改的
)和一个
id
(目标元素)。基于每个元素的哈希计算的修改

class CollectionChangedEvent {
  type: ChangeType,
  id: string
}

是否已经实施了类似的措施,或者有更好的方法来实现这一点?

也许这对您来说已经足够了:

class Observable extends EventEmitter {
  constructor(protected callback: Function) {
    super();
    this.on("change", callback);
  }
}

class Element extends Observable {

 constructor(public id: string, callback: Function) {
    super(callback);
  }

  private _propA: string;

  set propA(v: string) {
    this.emit("change", {changed: "_propA", newV: v, oldV: this._propA});
    this._propA = v;
  }
}

这是使用节点的EventEmitter的可观察属性的部分示例。

您是否查看了
.scan()
?我认为这是合适的。假设源代码是
source:Observable
,我会这样做:

const result:Observable<CollectionChangedEvent[]> = source
    .scan((previous, newElements:Element[]) => {
        const previousElements:Element[] = previous.elements;
        const newChanges = [];
        /* [...] Do huge comparison here, pushing each change you find between newElements and previousElements into newChanges */
        return {
            elements: newElements,
            changes: newChanges
        }
    }, { // Initial values: They are empty arrays
        elements: [],
        changes: []
    })
    .map(acc => acc.changes)
const结果:可观察=源
.scan((上一页,新元素:元素[]))=>{
const previousElements:Element[]=previous.elements;
常量newChanges=[];
/*[…]在这里进行巨大的比较,将您在新元素和以前的元素之间发现的每一个更改推到新的更改中*/
返回{
元素:新元素,
变化:新变化
}
},{//初始值:它们是空数组
要素:[],
更改:[]
})
.map(acc=>acc.changes)
差不多吧。如果您需要
结果
可观察到单个
CollectionChangedEvent
而不是数组,则可以
mergeMap
将其映射到
arr=>observable.from(arr)


或者你可以考虑做OpSITE,如果你有一个源代码流给你<代码> CopyCudioEnguts<代码>,那么你可以用<代码> SCAN()/<代码>建立<代码>元素< <代码>或<代码>元素[]/Cord>的结果。这应该更容易,因为您可以将每个事件视为命令,而不必比较数组的更改。

我从未使用过RxJS,但例如,redux通过比较数组是否相同来解决这一问题。顺便说一句,您不应该使用哈希来检查是否有更改,因为哈希最终会发生冲突。您是对的,可能像elementA.equals(elementB)这样的东西在这里更合适。。。我只是对解决可观测集合问题的一般方法感兴趣……不太感兴趣。如果您想拥有一些可能触发事件的属性,只需使用setter而不是普通属性。我想可能我没有明确说明这一点,但我感兴趣的是基于Rx的解决方案来处理集合中的更改(我并不真正使用node)。元素本身不应该发出事件,相反,这些元素的容器应该发出事件。
const result:Observable<CollectionChangedEvent[]> = source
    .scan((previous, newElements:Element[]) => {
        const previousElements:Element[] = previous.elements;
        const newChanges = [];
        /* [...] Do huge comparison here, pushing each change you find between newElements and previousElements into newChanges */
        return {
            elements: newElements,
            changes: newChanges
        }
    }, { // Initial values: They are empty arrays
        elements: [],
        changes: []
    })
    .map(acc => acc.changes)