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