我正在尝试对UI组件的Angular 15和RxJS可观察对象进行更被动的处理。我只订阅组件模板(html)中的数据。我有一个从外部系统接收数据的服务。我遇到的问题是数据可能会在多天内接收,需要“拆分”以供显示使用。
在显示画面中,有单独的数据组件,显示从服务调用返回的行。服务对外部主机进行HTTP调用。this.Entries$ = this.Http_.get<Array<IEntry>>('http://host.com/api/entry');
这个数据是一个带有EntryDate和信息结构(UserId、Description、TimeWorked等)的记录数组。外部API将所有记录作为一个平面数据数组发送回来,这个数组不保证排序,它按照数据库顺序返回,这是记录输入的顺序。任何处理都可能需要排序,但我不确定。
[
{ "EnterDate": 20221025, "UserId": "JohnDoe", "TimeWorked": 2.5, ... },
{ "EnterDate": 20221025, "UserId": "JohnDoe", "TimeWorked": 4.5, ... },
{ "EnterDate": 20221025, "UserId": "BSmith", "TimeWorked": 5, ... },
{ "EnterDate": 20221026, "UserId": "JohnDoe", "TimeWorked": 4, ... },
{ "EnterDate": 20221026, "UserId": "BSmith", "TimeWorked": 5, ... },
{ "EnterDate": 20221026, "UserId": "JohnDoe", "TimeWorked": 2, ... },
]
目前,我的HTML模板在Entries$ observable中循环,而它只循环了一天。
<ng-container *ngFor="let OneEntry of (Entries$ | async)">
<one-entry-component [data]=OneEntry />
</ng-container>
我希望能够按照EntryDate(显然还有user,但现在只使用EntryDate)将记录数组拆分为不同的数据集,类似于groupBy(),但我不知道如何获取内部记录引用,因为我相信它是groupBy()中的一个Map。
随着数据的分割,我将在页面上寻找多个一天组件,然后在其中有一个条目组件。
|---------------------------------------------------------------|
| |
| |-One Day 1-------------###-| |-One Day 2-------------###-| |
| | | | | |
| | [ One Line ] | | [ One Line ] | |
| | [ One Line ] | | [ One Line ] | |
| | [ One Line ] | | [ One Line ] | |
| | [ One Line ] | | [ One Line ] | |
| | | | | |
| |---------------------------| |---------------------------| |
| |
| |-One Day 3-------------###-| |-One Day 4-------------###-| |
| | | | | |
| | [ One Line ] | | [ One Line ] | |
| | [ One Line ] | | [ One Line ] | |
| | [ One Line ] | | [ One Line ] | |
| | [ One Line ] | | [ One Line ] | |
| | | | | |
| |---------------------------| |---------------------------| |
| |
|---------------------------------------------------------------|
如果回复中有4个不同的日期,那么4个框就会在那里。如果有2个不同的日期,那么只显示2个日期,但这可能是5或6个甚至。
我需要一个Observable,它包含拆分的日期(甚至用户),然后能够将其作为数据传递给<one-day-component [data]=OneDateOneUser$ />
。我的组件需要这个,以便我可以计算标题的时间条目,我相信这是一个简单的.pipe(map())操作。
在一天组件中,我将简单地循环OneDateOneUser$ observable,以提取要发送到一个条目组件的单个记录,就像我目前所做的那样。
我相信RxJS groupBy是我所需要的。但是,我是RxJS的新手,在示例中使用内部数据数组对我来说并不清楚。
如果数据是单个记录(如示例),而不是数据数组,则使用示例RxJS引用可以正常工作。
import { of, groupBy, mergeMap, reduce, map } from 'rxjs';
of(
{ id: 1, name: 'JavaScript' },
{ id: 2, name: 'Parcel' },
{ id: 2, name: 'webpack' },
{ id: 1, name: 'TypeScript' },
{ id: 3, name: 'TSLint' }
).pipe(
groupBy(p => p.id, { element: p => p.name }),
mergeMap(group$ => group$.pipe(reduce((acc, cur) => [...acc, cur], [`${ group$.key }`]))),
map(arr => ({ id: parseInt(arr[0], 10), values: arr.slice(1) }))
)
.subscribe(p => console.log(p));
// displays:
// { id: 1, values: [ 'JavaScript', 'TypeScript' ] }
// { id: 2, values: [ 'Parcel', 'webpack' ] }
// { id: 3, values: [ 'TSLint' ] }
但是,简单地将of()
中的数据更改为数组(更像是我的数据如何返回),就会发生故障,而且我不确定如何修复它:
import { of, groupBy, mergeMap, reduce, map } from 'rxjs';
of(
[
{ id: 1, name: 'JavaScript' },
{ id: 2, name: 'Parcel' },
{ id: 2, name: 'webpack' },
{ id: 1, name: 'TypeScript' },
{ id: 3, name: 'TSLint' }
]
).pipe(
groupBy(p => p.id, { element: p => p.name }),
mergeMap(group$ => group$.pipe(reduce((acc, cur) => [...acc, cur], [`${ group$.key }`]))),
map(arr => ({ id: parseInt(arr[0], 10), values: arr.slice(1) }))
)
.subscribe(p => console.log(p));
1条答案
按热度按时间ars1skjm1#
如果您只是将
Array<IEntry>
转换为Record<number, IEntry>
,其中包含类似lodash
的group by和map
RxJS操作符,会怎么样?然后,您可以使用模板上的一些
flex-wrap
和flex-row
功能获得所需的结果,只需循环记录的条目:Check this little working CodePen