Как превратить наблюдаемое в другое наблюдаемое - PullRequest
0 голосов
/ 27 октября 2018

Я начинаю с Rxjs для Angular 6, и у меня есть некоторые сомнения относительно того, как этого добиться:

У меня есть компонент списка карт, который будет отображать список с элементами, извлеченными из службы, которая возвращает наблюдаемое. Элементы типа данных разные. И наблюдаемая услуга может быть обновлена ​​новыми элементами, поэтому в списке карт должны отображаться эти новые элементы.

export class HomeComponent implements OnInit, OnDestroy {

  papers$:Observable<Paper[]>;

  papersPublished$:Observable<DataCard[]>;
  papersOnReview$:Observable<DataCard[]>;
  papersSubmitted$:Observable<DataCard[]>;

  constructor(private publicationService: PublicationService) { }

  ngOnInit() {
    this.papers$ = merge(
      this.publicationService.getAllPapersOnState("Submitted"),
      this.publicationService.getAllPapersOnState("OnReview"),
      this.publicationService.getAllPapersOnState("Published")
    );

        this.papersSubmitted$ = this.papers$.pipe(map(paper => [HomeComponent.paperToCard(paper,'Read', 'Review')]));
        this.papersOnReview$ = this.papers$.pipe(map(paper => [HomeComponent.paperToCard(paper,'Read', 'Accept')]));
        this.papersPublished$ = this.papers$.pipe(map(paper => [HomeComponent.paperToCard(paper,'Read', '')]));
      }

  private static paperToCard(paper, action_1_name, action_2_name): DataCard {
        // ... other code ...
  }
}

<app-cardlist
  [title]="'Published'"
  [description]="'Last science papers published. Yay!'"
  [items$]="papersPublished$"></app-cardlist>
<app-cardlist
  [title]="'On Review'"
  [description]="'Last papers on review. On publish way!'"
  [items$]="papersOnReview$"></app-cardlist>
<app-cardlist
  [title]="'Submitted'"
  [description]="'Last papers submitted for reviewing. Be the first one to check them!'"
  [items$]="papersSubmitted$"></app-cardlist>



export class PublicationService {
 // ... more code ...
 getAllPapersOnState(state: string): Observable<Paper[]> {
    return Observable.create(observer => {
      this.WF_SC.deployed().then(instance => {

        // State changed watcher to update on-live the observable
        const event = instance.AssetStateChanged({});
        event.on('data', (data) => {
          console.log('StateChanged catched!');
          this.getPaper((data['args']['assetAddress'])).then((paper) => observer.next(paper));
        });

        return instance.findAssetsByState.call(state);
      }).then(addresses => {
        addresses.forEach((address) => this.getPaper(address).then((paper) => observer.next(paper)));
      });
    });
  }
}


export class CardlistComponent implements OnInit {

  @Input() items$: Observable<DataCard[]>;

}

<div *ngIf="(items$ | async)" class="card-deck">
  <div *ngFor="let item of items$ | async" class="card" style="width: 18rem;">
    <!-- Other code -->
  </div>
</div>

Проблема в том, что в списке отображается только последний элемент. Как я могу преобразовать papers$:Observable<Paper[]> в $papersSubmitted$:Observable<DataCard[]>, чтобы иметь возможность передать его в CardlistComponent?

1 Ответ

0 голосов
/ 27 октября 2018

Вы, вероятно, хотите что-то вроде этого:

this.papersSubmitted$ = this.papers$.pipe(
  map((papers: Paper[]) => 
    papers.map((paper: Paper) => HomeComponent.paperToCard(paper, 'Read', 'Review')
  )
);

То же самое для всех подобных (и вы, конечно, должны также фильтровать их, как вы упомянули в комментариях).

Тогда,в вашей Службе сделайте следующее:

return Observable.create(observer => {
  // ...
}).pipe(toArray());

, чтобы вернуть Observable<Paper[]> вместо Observable<Paper>.

...