我在https://www.learnrxjs.io/operators/transformation/groupby.html
了解了分组依据但是,当我尝试仅按“类型”列进行分组时,却没有得到所请求的结果。
为了组成“类型”列然后显示在component.html上,我缺少什么部分?
您从订阅中获取类型的数据,然后通过订阅中的代码应用分组。
谢谢!
Stackblitz = https://stackblitz.com/edit/angular-twngjm
答案 0 :(得分:1)
您的操作方式:
服务:
Dataa() {
return this._http.get<any[]>('https://api.github.com/users'); // not a promise
}
组件:
_test; // not private
ngOnInit() {
this._test = this._apiService.Dataa().pipe( // set observable to variable
switchMap(data => from(data).pipe( // array to stream
groupBy((item: any) => item.type), // group by type
mergeMap(group => zip(of(group.key), group.pipe(toArray()))), // convert each group back to array and zip with key
reduce((acc, val) => acc.concat([val]), []) // collect emissions into array of arrays
))
);
}
模板:
<div style="display: flex;"> <!-- just styles into columns -->
<div *ngFor="let item of _test | async"> <!-- subscribe with async and iterate grouped arrays -->
{{item[0]}} <!-- first item is headers, display it -->
<div *ngFor="let user of item[1]"> <!-- second item is the grouped items, which you iterate -->
{{user.login}} <!-- show your data here -->
</div>
</div>
</div>
闪电战:https://stackblitz.com/edit/angular-cbnkjv?file=src%2Fapp%2Fapp.component.ts
说明:
首先,无需在此处转换为诺言。使用可观察物。模板中访问的变量也不能是私有的。
接下来,您的数据已经是数组,因此您需要使用switchMap-> from将其转换为流,以便groupBy可以对其进行操作,因为groupBy仅适用于流。
groupBy产生一个GroupedObservable,基本上是一堆由groupBy中指定属性分组的项目流。
因此,在那之后,您需要将Map合并到这些流中。然后使用组密钥将其压缩,然后将流转换为数组,就得到了[groupKey,[... group中的项目...]]这样的结构。
最后,mergeMap会逐个发出每个组,因此您可以使用reduce将它们全部收集到一个数组中
然后,您修改模板以使其与带有嵌套ngFors的该arrays数组结构一起使用。我还选择使用异步管道来处理我的订阅。
讨论:
这一切值得吗?除非您真正处理的是数据流(例如来自Web套接字或用户操作流),否则可能不会。无需将数组强制为可观察的组,然后再转换回数组并进行收集。您可以只使用lodash之类的实用程序库,并在其上同步运行地图运算符。如果这样做的话,代码将简化为这样:
ngOnInit() {
this._test = this._apiService.Dataa().pipe(
map(data => _.groupBy(data, 'type')),
map(grouped => Object.entries(grouped)) // _.groupBy gives a keyed object, this just converts to the same array of array structure as rx groupBy
);
}
真的不想要另一个依赖吗?简单的分组功能:
function groupBy(arr, prop) {
return arr.reduce((acc, val) => {
const key = val[prop];
acc[key] = (acc[key] || []).concat([val]);
return acc;
}, {});
}