可观察数组,查找值的索引

时间:2018-04-29 22:04:22

标签: angular rxjs rxjs5

我正在编写一个Angular应用程序,它可以从服务中获取一系列商店,作为Observable。

当用户点击地图上的标记时,我想获取存储在Observable中的数组中的商店索引。

stores: Observable<Store[]>;

ngOnInit() {
    this.stores = http.get<Store[]>('URL');
}

onMarkerClick(event) {
   const geopoint = event.geopoint;
   //How can I get the index where store.geopoint === event.geopoint?
}

2 个答案:

答案 0 :(得分:2)

要从阵列中过滤商店,请执行以下操作:

this.storesCollection.filter(store => store.geopoint === event.geopoint); // -1 if not found

要将Observable转换为数组,请使用map:

this.stores$.map((stores: Stores[]) => this.storesCollection = stores)

您不需要执行subscribe(),因为http会返回一个热门观察者,无论是否有订阅者,总是会触发

答案 1 :(得分:1)

如果您想从后端懒洋洋地获取store[],则必须在第一次订阅this.stores时获取这些内容。所有其他订阅可能使用从http.get返回的相同值。为了实现这一目标,我们可以使用.shareReplay()让所有订阅者多播到同一个源,让它重放以前的值而不是重新调用http.get

function getStores() {
  //return http.get<Store[]>(URL) 
  return Rx.Observable.from(['asdf', 'foo', 'bar']).delay(500);
}

const stores = getStores()
  .do(undefined, undefined, _ => console.log('retrieved values from http backend'))
  .shareReplay();
const $buttonClicks = Rx.Observable.fromEvent(document.getElementById('button'), 'click');

$buttonClicks
  .do(_ => console.log('CLICKED'))
  .switchMap(_ => stores
               .map((val, idx) => [val, idx])
               .filter(tuple => tuple[0] === 'foo')
               .map(tuple => tuple[1])
            )
  .subscribe(
    idx => console.log('got index of `foo`: ' + idx)
  );

switchMap有点难看(map / filter / map),因为这个示例代码不使用数组而是使用单个发射。 .toArray()可以解决此问题。取决于您希望如何继续使用索引(或值)