在RxJS和Angular

时间:2018-06-06 02:57:43

标签: angular rxjs observable reactive-programming

假设有一个电子邮件收件箱。最初的50封电子邮件在初始页面加载时加载。

从那时起,任何新的传入电子邮件都应显示在列表的顶部。

复杂因素是用户可以通过向下滚动到页面底部来进行分页。这会将下一页数据加载到列表的底部。

我想知道如何使用Angular和RxJS实现这一目标。最初我想要Subject<Email>我可以调用next(email)将其推送到流中,但是由于我们需要追加和前置,所以这不起作用。

另一个复杂因素是新电子邮件应该是动画的(即淡入)。

我打算按如下方式渲染:

<email *ngFor="let email of (emails$ | async)">...</email>

相反,我正考虑将其更改为以下内容:

<div class="new-emails" *ngFor="let email of (newEmails$ | async)">...</div>
<div class="initial-emails" *ngFor="let email of (initialEmails$ | async)">...</div>
<div class="older-emails" *ngFor="let email of (oldEmails$ | async)"></div>

这是问题的标准解决方案还是我可能缺少一些RxJS来简化这个问题?

1 个答案:

答案 0 :(得分:1)

大家好,我可能会使用像CodeSandbox这样的递归策略,演示使用的是主题。

这是一个带有递归项结构的snipet,后面是数据提要的模拟请求服务。

总的来说,只要我的服务Subject使用.next()更新,我只是在调用相同的项目,棘手的部分是您必须使用{{1}在您的主题订阅上,因为否则订阅将不会被取消订阅,即使您将取消订阅逻辑放在pipe(first())中(在销毁时不会调用,因为实际上您只是潜水在递归中越来越多而不分离任何组件)这将破坏您的可视化逻辑。

onDestroy

// Typescript
import { Component, Input } from "@angular/core";
import { InfinityScrollFeedService } from "./../services/infinity-scroll-feed.service";
import { first } from "rxjs/operators";

@Component({
  selector: "app-recursive",
  templateUrl: "./recursive.component.html",
  styleUrls: ["./recursive.component.css"]
})
export class RecursiveComponent {
  @Input() initialData;
  @Input() page;
  nextLayer = [];

  constructor(private feed: InfinityScrollFeedService) {}

  ngOnInit() {
    this.feed.httpCallMocker.pipe(first()).subscribe(data => {
      this.nextLayer = data;
    });
  }

  loadMore() {
    this.feed.retrivePackage(Number(this.page) + 1);
  }
}
// Template

<div class="row" *ngFor="let row of initialData">
	<div>Name: {{row.name}}</div>
	<div>Age: {{row.age}}</div>
</div>

<div *ngIf="nextLayer.length > 0">
	<app-recursive [initialData]="nextLayer" [page]="(page+1)">
	</app-recursive>
</div>
<button *ngIf="nextLayer.length <= 0" (click)="loadMore()">Show more</button>

// Css 
.row {
  display: flex;
  justify-content: space-between;
  border: 1px solid red;
}