在Angular中,如何在同一页面显示原始数据和过滤后的数据?

In Angular, how to display original data and filtered data on the same page?

假设我有一些来自服务调用的数据,我将其存储为 originalData

现在除此之外,我必须过滤数据并显示过滤后的数据。我这样做的方式是这样的:

this.service.getData((data) => {
  this.originalData = data;
  this.filteredData = data.filter(/* some filter condition */);
});

我在 html 模板上绑定了 originalDatafilteredData。该解决方案有效。由于我需要显示越来越多的过滤版本,因此我在我的 class.

上存储了越来越多的这些过滤或以其他方式修改的对象

这似乎是一个不好的做法,因为我的 class 的状态正在增加并失去控制,并且管理数据的不同副本变得越来越麻烦。

更好的做法是什么?

转换数据

您只想转换现有数据。这里有两个非常简单的示例,说明如何同步和异步地执行此操作。因为通常来自服务的数据是异步的。

同步

对于同步数据,您可以只使用一个将您的数据作为参数的函数,returns 转换数据的所需形式。

component.ts:

data = [10, 20, 30, 40, 50, 60]

divisibleBy20(numbers: number[]) {
  return numbers.filter(number => number % 20 === 0)
}

component.html:

{{ data }}
{{ divisibleBy20(data) }}

异步

对于异步数据,RxJS 提供了大量的操作符来传输数据。您可以找到更多运算符 here.

Service.ts:

getData() {
  return of([1, 2, 3, 4, 5, 6]);
}

Component.ts:

all$: Observable<number[]>
evens$: Observable<number[]>

constructor(
  private dataService: DataService
){}

ngOnInit() {
  this.all$ = this.dataService.getData()
  this.evens$ = this.all$.pipe(
    map((numbers: number[]) => numbers.filter(number => number % 2 === 0))
  )
}

Component.html:

{{ all$ | async }}
{{ evens$ | async }}

这是一个供您在 Stackblitz 上玩的示例。

根据 Angular 文档,这是 what NOT to do 的示例。 这种管道有它们的用途,但可以无缘无故地触发很多。为了防止这种情况,您可以制作自定义管道 'pure'。这样 Angular 只有在检测到输入值发生纯粹变化时才执行管道。

您可以通过将 pure: true 添加到装饰器来实现:

@Pipe({
  name: 'myPipe',
  pure: true
})
export class MyPipe implements PipeTransform {
    // ...
}