使用RXJS将项目添加到可观察对象数组后,如何触发可观察值发射?

时间:2019-04-28 18:51:19

标签: angular typescript rxjs observable

我的服务中有一个可观察的数组:

gearItems$: Observable<GearItem[]>;

此数组在构造函数中实例化以用于测试:

constructor() 
  {
    this.gearItems$ = of([
      { ID: 1, name: 'T-shirt', price: 10, sizes: [
        { size: Size.L, available: false , color: 'warn' }, ,
      ], inStock: true, images: [
        { ID: "1", name: "image1", size: 12, type: "type", url: "../../../assets/IMG_5585.JPG" },
        { ID: "123", name: "image2", size: 12, type: "type", url: "../../../assets/IMG_5904.JPG" }
      ]...)
  }

我需要更新/添加该数组中的单个项目并触发新的值发射:

updateGearItem(gearItem: GearItem): Observable<GearItem>{
    return this.gearItems$.pipe(
      flatMap((gearItems: GearItem[]) => {
        return gearItems.filter(gI => gI.ID !== gearItem.ID);
      })
    )
  }

  createGearItem(gearItem: GearItem): Observable<any>{
    // create HTTP request to the backend to create a new item
    return this.gearItems$.pipe(
      map(gearItems => {
        gearItems.push(gearItem)        
        return gearItems;
      })
    )       
  }

但是我不能这样做。在ngOnInit的组件中,我有一个订阅,正在监听gearItems$: Observable<GearItem[]>;可观察的数组:

ngOnInit() {    
    this.merchandiseService.fetchAllGearItems().subscribe(
      (gearItems: GearItem[]) => this.gearItems = gearItems
    );
  }

但是,每当我尝试添加或更新可观察数组中的项目时,都不会发生任何事情。我在这里想念什么?

2 个答案:

答案 0 :(得分:0)

要发出价值更改,可以使用BehaviorSubject和Observable。每次调用下一个方法时,BehaviorSubject都会发出新值(例如,从http.get获取数据)。用于处理应用程序生命周期事件的订阅,在组件销毁之前,我们应该取消订阅。

private itemsSubject = new BehaviorSubject<GearItem[]>(null);
items: Observable<GearItem[]>;
subscribtion: Subscription;

gearItems$: Observable<GearItem[]>;

constructor() 
{
    this.items = this.itemsSubject.asObservable();
    ... [rest of code] ...
}

createGearItem(gearItem: GearItem): Observable<any>{
    // create HTTP request to the backend to create a new item
    return this.items.pipe(
      map(gearItems => {
        this.itemsSubject.next(gearItems); // this line emits new value
        return gearItems;
      })
    )       
}

ngOnInit() {    
    this.subscribtion = this.items.subscribe(
      (gearItems: GearItem[]) => gearItems$ = gearItems;
    );
}

ngOnDestroy(): void {
    this.subscribtion.unsubscribe();
} 

答案 1 :(得分:0)

以下是简单形式的解决方案。

addItem将获取BehaviorSubject中当前的内容,并附加一个新项作为副作用。请注意,第一个first()是为了确保我们仅从BehaviorSubject获取最新值,否则它将继续发出,因为在后续tap()中有一个.next。最后的first()是完成可观察的

const items = new BehaviorSubject([])
const addItem =
  (item) => items.pipe(
    first(),
    tap(arr => items.next([...arr, item])),
    first(),
  )
items.subscribe(console.log)
addItem('a').subscribe()
addItem('b').subscribe()
addItem('c').subscribe()