首页 文章

如何比较Observables:NGRX和使用Observable的Observables进行有效的Angular 4渲染

提问于
浏览
0

OVERVIEW

遵循容器 - >组件模式并使用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(谓词)之类的RxJs函数来指定何时实际触发组件中的订阅 .

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

PROBLEM & QUESTION

有两个问题

  • 使用我们的Observable数组 - 什么是比较两个Observable的值的最佳方法,看看是否有任何改变

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

  • 使用Observable的Observable,以便不同的子组件可以定义触发订阅的标准,从而使其他区域更加困难 . 有更好的方法吗?

Example:

儿童比赛

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

1 回答

  • 0

    我这样做的方法是只发送一个值并从中派生出可观察量而不是发送可观察量的可观察量 .

    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));
    

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

    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真正做的事情,它使用扫描操作符,它获取您累积的vallue(最后一个值)和您的新操作(您的更新)并以这样的方式应用更改,即只需要更新的部分得到更新(减速机) . ngrx的“select”函数也会处理所有distinctUntilChanged()内容,因此您无需担心它 .

相关问题