Angular + rxjs:集合过滤的模式,其中过滤器和集合是流

时间:2017-11-07 15:36:56

标签: angular rxjs

有没有更好的方法来写这个。我想加载一些数据,订阅一个在下拉列表中加载的行为主题,我想要过滤数据的每一个更改。它的工作原理但不确定这是使用嵌套BehaviorSubject编写它的最佳方法,还是应该在forkJoin的已完成事件中订阅,而forkJoin是从http

加载数据的
ngOnInit() {

//load all the data

let array1: Observable<any[]> = this.service1.getAll();

let array2: Observable<any[]> = this.service2.getAll();    

let observableBatch = [array1, array2];


Observable.forkJoin(observableBatch).subscribe(data => {

  this.items1 = data[0] as Array<any>;

  this.items2 = data[1] as Array<any>   


  //subscribe to BehaviorSubject Observable, filter on every change        
  this.someService.selectedItem$.subscribe((item: any) => {

    if (item) {         

      this.filterItemsByItemId(item.itemId);
    }

   }, (error:any)=>{

  //error

});     


}, (error: any) => {

  //error


});

}

2 个答案:

答案 0 :(得分:1)

你有一个嵌套订阅的事实真的很奇怪。 通常我使用以下方法(假设您只加载一次所有数据):

@Component({
 changeDetection: ChangeDetectionStrategy.OnPush
})
export class FooComponent {
  dataOne$: Observable<any[]>; // depending on if you use the unfiltered collections or not this members can be removed
  dataTwo$: Observable<any[]>;

  selected$: Observable<any>;    
  filteredOne$: Observable<any[]>;
  filteredTwo$: Observable<any[]>;

  constructor(){
   this.dataOne$ = this.service1.getAll()
     .share(); // avoid multiple requests for this data
   this.dataTwo$ = this.service2.getAll()
     .share(); // avoid multiple requests for this data

   this.selected$ = this.someService.selected$; // this should be an exposed observable, not the Subject itself

   filteredOne$ = this.selected$
    .withLatestFrom(this.dataOne$,(selected,elements)=>({selected,elements}))
    .map(data => elements.filter(element => //add filter logic using data.selected));
   filteredTwo$ = this.selected$
    .withLatestFrom(this.dataTwo$,(selected,elements)=>({selected,elements})
    .map(data => elements.filter(element => // add filter logic using data.selected));    
  }
}

}

我用这个存档的内容:

  • 更改检测
  • 主要使用async管道从observables中提取数据

使用此方法,您可以使用模板中的selected$流来呈现当前值,并使用filtered$流来呈现相应集合的已过滤元素。

如果数据集合可以发出新值,那么我通常使用静态 combineLatest运算符而不是withLatestFrom。两者之间的差异解释为here

相信我这个:无论你在哪里订阅,你的代码都可以重构为(ab)使用async管道:D

答案 1 :(得分:0)

我没有看到你的数据加载有问题,困扰我的是behaviorSubject。当你在Angular中有输入绑定时,为什么要这样做呢?

我猜您的下拉列表是<select>。这给了

<select #myDropdown (change)="changeValue(myDropdown.value)">
  <option value="0">0</option>
</select>

在您的组件中:

changeValue(value) {
  // Let's say you request an endpoint
  this.myService.myMethod(value).subscribe(data => /* do your thing here */);

  // Want to filter your data ? No problem 
  this.items1 = this.items1.filter(item => item['your property here'] === value);
  this.items2 = this.items2.filter(item => item['your property here'] === value);
}

这似乎更简单,更短,不是吗?