rxjs наблюдаемый - избегайте рекурсивных назначений - PullRequest
0 голосов
/ 11 мая 2018

Я ищу идеи для улучшения кода ниже, я начну с описания проблемы и дам свое решение, которое я ищу для улучшения.

Код Angular 4 (TS)

herelistOfItems$: Observable<Array<Item>>;

// Getting list of items from the backend 
init() {
  this.listOfItems$ = http.get('/getItems'); 
}

// - Check if item already exits (show error and stop if exists)
// - If not add the item (http request)
// - Refresh by getting get the updated list from the backend (http request)
onClickAddNewItem(newItem: Item) {
   this.listOfItems$ = this.listOfItems$
                             .filter(/* validate item is not exits */)
                             .concatMap(_ => http.post('/addItem', newItem))
                             .switchMap(_ => http.get('/getItems'))
                             .catch((err) => ...);
}

HTML-код будет выглядеть примерно так:

<div *ngFor="let item of listOfItems$ | async">...

Проблема с этим кодом - рекурсивное назначение this.listOfItems$ = this.listOfItems$...

одним из возможных решений может быть

onClickAddNewItem(newItem: Item) {
   this.listOfItems$
       .filter(/* validate item is not exits */)
       .concatMap(_ => http.post('/addItem', newItem))
       .subscribe(_ => this.listOfItems$ = http.get(...), err => ... );

}

Я ищу более элегантный способ обновить список, не подписываясь на него, есть идеи?(Я знаю, что могу решить это с помощью ngrx \ store, но я не использую его в этом проекте)

Спасибо за вашу помощь

1 Ответ

0 голосов
/ 11 мая 2018

Вы можете создать наблюдаемый поток из событий щелчка, где вы обычно запускаете onClickAddNewItem.

@ViewChild() addButton;

this.listOfItems$ = this.http.get('/getItems').pipe(
  switchMap(items => fromEvent(this.addButton.nativeElement, 'click').pipe(
    startWith(items),
    filter(/* ... */)
    mergeMap(newItem => this.http.post('/addItem', { newItem })),
    switchMap(() => this.http.get('/getItems')),
  ),
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...