繁体   English   中英

如何比较可观察对象:NGRX和使用可观察对象的可观察对象进行有效的Angular 4渲染

[英]How to compare Observables: NGRX and Working with Observables of Observables for efficient Angular 4 Rendering

总览

遵循容器->组件模式,并使用ngrx集中我们的应用程序状态。

应用程序的结构如下:

Container
   Child_Comp_1
      Child_Comp_2
         Child_Comp_3

最初,只有一个可观察的数据可以在Container上订阅,然后将相对数据作为输入传递给子组件。

Observable<
 {
   data,
   collection: []
 }> 

但是,任何更新都会触发ngrx选择器,并导致AngularJS重新渲染组件链。

我们开始提供可观察物,

Observable< 
 {
  data: Observable<data>
  collection: Observable<Observable<Item>[]>
 }>

现在,我们可以使用诸如DistinctUntilChanged(predicate)之类的RxJs函数来指定何时实际触发组件中的订阅。

并使用ChangeDetection.markForCheck()它将限制重新渲染的位置

问题与问题

有两个问题

  1. 以我们的Observable数组-比较两个Observable的值以查看是否有任何更改的最佳方法是什么

例:
collection.distinctUntilChanged((a, b) => ?? compare values of ab ??)

  1. 使用Observables的Observables,以便不同的子组件可以定义何时触发订阅的标准,这会使其他区域更加困难。 有没有更好的方法?

例:

儿童比赛

  collection
   .distinctUntilChanged((a, b) => a.length === b.length)
   .subscribe(items => ....)  // only fired if length changed

我这样做的方法是只发送一个值并从中获取可观察值,而不是发送可观察值的可观察值。

private subj: Subject<{data:any, collection: any[]}> = new Subject<{data:any, collection: any[]}>();
src$: Observable<{data:any, collection: any[]}> = this.subj.distinctUntilChanged();
data$: Observable<any> = this.src$.pluck('data').distinctUntilChanged();
collection$: Observable<any[]> = this.src$.pluck('collection').distinctUntilChanged();

this.src$.subscribe(v => console.log(v));
this.data$.subscribe(v => console.log(v));
this.collection$.subscribe(v => console.log(v));

uniqueUntilChanged的默认行为是对象引用(或原始)比较。 因此,关键是强制实现对象不变性,并且仅更改需要更新的对象,并在需要时重新引用它们。

const obj = { data: {}, collection: []; };
this.subj.next(obj); // all subscribers trigger
const dataUpdate = Object.assign({}, obj, {data: { prop1:'new Val' }}); // change only the data property, collection untouched
this.subj.next(dataUpdate); //src and data trigger
const collUpdate = Object.assign({}, dataUpdate, { collection: [1] }); // change only collection property, data untouched
this.subj.next(collUpdate); //src and coll fire
const collUpdate2 = Object.assign({}, collUpdate, { collection: collUpdate.collection.concat([2]) }); // add to existing collection
 this.subj.next(collUpdate2); //src and coll fire
const collUpdate3 = Object.assign({}, collUpdate2, { collection: collUpdate2.collection.splice(0,1) }); //reomve from existing collection
 this.subj.next(collUpdate3); //src and coll fire

这是常规模式,采用您的最后一个值以及您的更新,并以仅更新应更新的片段(包括其所有祖先)的方式应用更新。 这就是ngrx真正在做的事情,它使用扫描运算符,该运算符将获取您累积的价值(最后一个值)和新操作(您的更新),并以仅需更新的部分进行更新的方式应用更改(减速器)。 ngrx的“选择”功能还可以处理所有与众不同的UntilChanged()内容,因此您无需担心。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM