【问题标题】:How transform observable into another observable如何将 observable 转换为另一个 observable
【发布时间】:2018-10-27 14:45:20
【问题描述】:

我从 Angular 6 的 Rxjs 开始,我对如何做到这一点有一些疑问:

我有一个卡片列表组件,它将显示从服务中获取的项目列表,该服务返回一个可观察的。数据类型项目不同。并且 service observable 可能会更新新项目,因此卡片列表应该显示这些新项目。

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&lt;Paper[]&gt; 转换为$papersSubmitted$:Observable&lt;DataCard[]&gt; 以便能够将其传递给CardlistComponent

【问题讨论】:

  • 请说明您是如何从家里给您的CardlistComponent 打电话的。不过,您的 papersSubmitted$ 和类似的 observable 看起来很可疑,它们看起来会包含所有论文的卡片,而不仅仅是提交/审查/已发布的卡片。
  • 是的,过滤器还没有实现。刚才三个列表应该显示相同的信息。这个想法是让所有论文都有一个可观察的,然后过滤以将它们传递到 CardList。我在 HomeComponent 下方附加了代码

标签: angular6 rxjs6


【解决方案1】:

你可能想要这样的东西:

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

所有相似的都一样(当然你也应该过滤它们,正如你在 cmets 中提到的那样)。

然后,在您的服务中,执行以下操作:

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

返回Observable&lt;Paper[]&gt; 而不是Observable&lt;Paper&gt;

【讨论】:

  • Mmh... 这会显示错误:“TypeError:papers.map 不是函数”。 console.log(papers) 显示的是一篇论文而不是数组。我认为是因为服务性能observer.next(paper);它应该是observer.next([paper]);
猜你喜欢
  • 2018-10-23
  • 2021-10-27
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-24
  • 1970-01-01
相关资源
最近更新 更多