angular - 如何让 RxJS observable 管道访问原始 observable 的发射和管道之前的发射?

标签 angular rxjs angularfire2 rxjs-pipeable-operators immer.js

我有一个 RxJS Observable,它对底层数据结构发出一系列更改 - 具体来说,snapshotChanges() from an AngularFirestoreCollection .

  • 我目前正在将其映射到一组纯 JavaScript 对象以供我的应用使用。
  • 此数组不受任何方式保护,使用代码可能会意外修改此结构。
  • 每当底层数据源发出时,都会重建整个数组,即使数组中只有一项(有时甚至没有)实际发生更改。
  • 因此,所有引用每次都会发生变化,使得更改检测变得比实际需要的更加困难,并且确实减慢了我的应用的速度。

我想做的是使用 Immer维护不可变的结构,以便未更改的数据在结构上与"new"数组共享。

我无法解决的是如何将 pipe() 关闭 snapshotChanges() observable,以便管道可以访问先前发出的不可变数据(或首次默认)除了最新的 snapshotChanges() 输出。

在代码中,我基本上已经拥有的是:

const docToObject = (doc) => { /* change document to fresh plain object every time */ };
const mappedData$ = snapshotChanges().pipe(
    map(changes => changes.map(change => docToObject(change.payload.doc)),
    tap(array => console.log('mutable array:', array)),
);

我本质上是在寻找这样的东西,但我不知道 XXX(...) 应该是什么:

const newImmutableObject = (changes, old) => {
  // new immutable structure from old one + changes, structurally sharing as much as
  // possible
};
const mappedData$ = snapshotChanges().pipe(

// ==================================================================================
    XXX(...), // missing ingredient to combine snapshotChanges and previously emitted
              // value, or default to []
// ==================================================================================

    map(([snapshotChanges, prevImmutableOutput]) => newImmutableOutput(...)),
    tap(array => console.log('IMMUTABLE ARRAY with shared structure:', array)),
);

我感觉像the expand operator接近我需要的,但它似乎只在后续运行中传递先前发出的值,而我还需要新发出的 snapshotChanges

给定一个 RxJS Observable 管道,我如何操作此 Observable 的排放,同时还可以访问该管道之前的排放?

最佳答案

根据您的要求,我建议使用 scan 运算符,它可以跟踪所有以前的状态和新状态。

const newImmutableObject = (changes, old) => {
  // new immutable structure from old one + changes, structurally sharing as much as
  // possible
};
 const mappedData$ = snapshotChanges().pipe(
 scan((acc, current) => [...acc, current], []), //<-- scan is used here
 map(([snapshotChanges, prevImmutableOutput]) => newImmutableOutput(...)),
    tap(array => console.log('IMMUTABLE ARRAY with shared structure:', array)),
);

关于angular - 如何让 RxJS observable 管道访问原始 observable 的发射和管道之前的发射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53235649/

相关文章:

angular - 'NgIf' 既不是 'ComponentType' 也不是 'DirectiveType'

angular - 如何在angular2的子模块组件中使用父模块组件

angular - 将 Angular2 Http 响应转换为 ConnectableObservable

rxjs - RxJ 中的 Observable.onSubscribe 等效项

angular - FIRESTORE (4.10.1) 内部断言失败 : AsyncQueue is already failed: The requested version (1) is less than the existing version (2)

angular - 未定义标识符 'title'。 '__object' 不包含这样的成员

Angular Material 6.0.1 树默认打开并全部展开/折叠

javascript - 在新选项卡中的组件之间传递数据

angular - 为什么 HttpErrorResponse 的实例不会触发使用 HttpClient 在 Angular 中订阅服务器响应的错误函数?

Firebase AngularFire2从数据库获取对象