数组的可观察性,找到值的索引

Observable of array, find index of value

我正在编写一个 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?
}

从数组中筛选商店:

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

并使用映射将 Observable 转换为数组:

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

您不需要执行 subscribe() 因为 http returns 是一个热门的可观察对象,无论是否有订阅者都会触发

如果您想从后端延迟获取 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() 可以解决这个问题。取决于您希望如何继续使用索引(或值)