Как вызвать выброс наблюдаемой величины после добавления элемента в массив наблюдаемых с помощью RXJS? - PullRequest
0 голосов
/ 28 апреля 2019

У меня есть наблюдаемый массив в моем сервисе:

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 голосов
/ 29 апреля 2019

Вот решение в простой форме.

addItem извлечет то, что в данный момент находится в BehaviorSubject, и добавит новый элемент в качестве побочного эффекта.Обратите внимание, что 1-й first() должен убедиться, что мы принимаем только последнее значение из BehaviorSubject или оно будет продолжать излучать, потому что в последующем tap() есть .next.Последний первый () должен завершить наблюдаемое

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()
0 голосов
/ 28 апреля 2019

Для получения изменений значений вы можете использовать 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();
} 

...