从“角度”的可观察列表中获得可观察的项目

时间:2019-11-12 18:58:07

标签: angular rxjs observable

我在服务中有一个项目列表,还有一个将该列表包装成可观察的吸气剂。
可观察值在带有async管道的组件视图中使用,并且按预期方式工作。列表更新后,视图也会更新。

我还有一个不同的组件,需要根据ID从该列表中获取特定项目的可观察物。
问题是,具有该ID的项目在被请求时可能还不在列表中。 我该如何实现呢?

我尝试过的一些例子:

export class ItemsService {
  private itemList: Item[] = [];

  constructor() {
    // get the list from the backend    
  }

  // This is fine
  getItemList(): Observable<Item[]> {
    return of(this.itemList);
  }

  // This I assume does not work, because the pipe just applies map 
  //on whatever is now in the observable list
  getItem(id: string): Observable<Item> {
    return this.getItemList().pipe(map(items => items.find(item => item.id === id)));
  }

  // This I assume does not work as the local item is not yet set when I wrap it in an observable
  //to return it, and when it eventually gets set by the callback, it's already out of scope.
  // The weird thing to me is that the callback is only called at the beginning, when the list is empty,
  //and not anymore when the list gets populated
  getItem(id: string): Observable<Item> {
    let item: Item;
    this.getItemList().subscribe(items => {
      console.log('callback called');
      item = items.find(item => item.id === id);
    });
    return of(item);
  }
}

3 个答案:

答案 0 :(得分:1)

尝试一下:

getItem(id: string): Observable<Item> {
  return this.getItemList().pipe(
    map(items => items.find(item => item.id === id)),
  );
}

答案 1 :(得分:1)

在给定元素可用时获取通知的一种可能方法是使用主题。

将此添加到您的服务中

private subject = new Subject<Item>();

一旦收到数据,就循环遍历并将其提供给主题。

  this.itemList.forEach((item: Item) => {
    this.subject.next(item);
  });

第三部分是获取通知。

  getItem(id: string): Observable<Item> {
    return this.subject
      .pipe(
        filter((item: Item) => item.id === id)
      )
  }

从组件中使用它,如下所示:

  ngOnInit() {
    const waitForElementWithId = 'b1';

    this.itemsService.getItem(waitForElementWithId).subscribe(x => {
      console.log(`${waitForElementWithId} is here`);
    });
  }

工作Stackblitz

答案 2 :(得分:0)

我同意你的看法。调用getItemList()时,itemList变量为空。 确保将调试器放入getItem()中,并检查itemList:

  getItem(id: string): Observable<Item> {
    let item: Item;

    console.log(this.itemList);

    debugger;

    // see whether itemList is empty or not;
    // if it's empty, the below function - getItemList() - return an observable with empty value.

    this.getItemList().subscribe(items => {
      console.log('callback called');
      item = items.find(item => item.id === id);
    });
    return of(item);
  }

重点是包含{return of(itemList)}的getItemList不会监视itemList的新值。

当从服务器获取数据完成后,您可以改为使用主题 next(data),然后订阅该主题。< / p>