RxJS和ANGULAR:基于特定的';键';使用RxJS
我正在获取这个JSON数据,它是一个对象数组,我需要对它进行重组/重新排序,以便在我的组件中呈现信息 当前结构:RxJS和ANGULAR:基于特定的';键';使用RxJS,angular,rxjs,Angular,Rxjs,我正在获取这个JSON数据,它是一个对象数组,我需要对它进行重组/重新排序,以便在我的组件中呈现信息 当前结构: [ { "name": "Rahul", "class": 3, "gender": "M", "section": "B", "rollNumber": "1231", "sports": [ "Badminton", "Chess" ], "age": 7 }, { "na
[
{
"name": "Rahul",
"class": 3,
"gender": "M",
"section": "B",
"rollNumber": "1231",
"sports": [
"Badminton",
"Chess"
],
"age": 7
},
{
"name": "Rajat",
"class": 5,
"gender": "M",
"section": "C",
"rollNumber": "123122",
"sports": [
"Chess"
],
"age": 9
},
]
class 4
section A
name
section B
name
class 5
section A
name
section B
name
.
.
.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, from, of, zip, pipe } from 'rxjs';
import { groupBy, mergeMap, toArray, map, tap} from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class ConfigService {
const studentURL = 'https://student-management-api-1u3cd4j7s.now.sh/students';
constructor(private http: HttpClient) { }
public getStudents(): Observable<any> {
const studentList = this.http.get(this.studentURL);
.tap(result => result.json());
from(studentList)
.pipe(
groupBy(studentList => studentList.class),
mergeMap(group => zip(of(group.key), group.pipe(toArray())))
)
.subscribe(console.log('studentList', studentList));
return studentList;
}
}
所需结构:
[
{
"name": "Rahul",
"class": 3,
"gender": "M",
"section": "B",
"rollNumber": "1231",
"sports": [
"Badminton",
"Chess"
],
"age": 7
},
{
"name": "Rajat",
"class": 5,
"gender": "M",
"section": "C",
"rollNumber": "123122",
"sports": [
"Chess"
],
"age": 9
},
]
class 4
section A
name
section B
name
class 5
section A
name
section B
name
.
.
.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, from, of, zip, pipe } from 'rxjs';
import { groupBy, mergeMap, toArray, map, tap} from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class ConfigService {
const studentURL = 'https://student-management-api-1u3cd4j7s.now.sh/students';
constructor(private http: HttpClient) { }
public getStudents(): Observable<any> {
const studentList = this.http.get(this.studentURL);
.tap(result => result.json());
from(studentList)
.pipe(
groupBy(studentList => studentList.class),
mergeMap(group => zip(of(group.key), group.pipe(toArray())))
)
.subscribe(console.log('studentList', studentList));
return studentList;
}
}
我在rxjs中使用了groupBy()和mergeMap()进行了尝试
这是我的角度服务:
[
{
"name": "Rahul",
"class": 3,
"gender": "M",
"section": "B",
"rollNumber": "1231",
"sports": [
"Badminton",
"Chess"
],
"age": 7
},
{
"name": "Rajat",
"class": 5,
"gender": "M",
"section": "C",
"rollNumber": "123122",
"sports": [
"Chess"
],
"age": 9
},
]
class 4
section A
name
section B
name
class 5
section A
name
section B
name
.
.
.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, from, of, zip, pipe } from 'rxjs';
import { groupBy, mergeMap, toArray, map, tap} from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class ConfigService {
const studentURL = 'https://student-management-api-1u3cd4j7s.now.sh/students';
constructor(private http: HttpClient) { }
public getStudents(): Observable<any> {
const studentList = this.http.get(this.studentURL);
.tap(result => result.json());
from(studentList)
.pipe(
groupBy(studentList => studentList.class),
mergeMap(group => zip(of(group.key), group.pipe(toArray())))
)
.subscribe(console.log('studentList', studentList));
return studentList;
}
}
component.html文件
import { Component, OnInit } from '@angular/core';
import { ConfigService } from '../config/config.service';
@Component({
selector: 'app-class-component',
templateUrl: './class-component.component.html',
styleUrls: ['./class-component.component.css']
})
export class ClassComponentComponent implements OnInit {
students: object;
constructor(private data: ConfigService) {}
ngOnInit() {
this.data.getStudents().subscribe(data => {
this.students = data;
console.log(data);
});
}
}
<div class='container'>
<ul *ngFor="let student of students; let i = index">
<h3> Class {{ student.class }}</h3>
<li *ngFor="let section of students; let i = index">
<h5> section {{ student.section}}</h5>
<!-- <a href='#' *ngFor="let name of students">{{student.name}}</a> -->
</li>
</ul>
</div>
班级{{student.Class}
-
第{{student.section}
我认为在获取之后,最好在服务本身中重新构造/重新排序。不确定我哪里出错了,我遗漏了什么。步骤1:您将获得一个阵列,它将发射整个阵列,以便groupBy工作。您需要发射所有值,因此这里使用switchMap,我们将从中发射阵列的所有条目 步骤2:groupBy将给出另一个观察值,您需要将其合并以查看分组结果。所有组现在都将作为值发射 在下面的示例中,类3和5可以有两个组,因此subscribe函数中的最终结果将被调用两次,一次调用类3,另一次调用类5 第3步:如果您想更深入,请重复groupBy和mergeMap
this.http.get(this.studentURL).pipe(
switchMap(val => from(val)),
groupBy(studentList => studentList.class),
mergeMap(group => group.pipe(toArray())),
map(studentList => ({['class' + studentList[0].class]: studentList }))
)
闪电战:
更新2:解决方案 服务:
public getStudents(): Observable<any> {
return this.http.get<any[]>(this.studentURL)
.pipe(
switchMap(val => from(val)),
groupBy(studentList => studentList.class),
mergeMap(group => group.pipe(toArray())),
map(studentList => ({
[studentList[0].class]: studentList.reduce((sections, student) => ({...sections, [student.section]: [...(sections[student.section] || []), student]}), {})
})),
scan((response, studentList) => ({...response, ...studentList}), {})
);
}
students$: Observable<any>;
// you can hook up the observable here
// in template you can use the the async pipe
// to subscribe to the observable
ngOnInit() {
this.students$ = this.service.getStudents();
}
<div class='container'>
<ul *ngFor="let classItem of students$ | async | keyvalue; let i = index">
<li> Class {{ classItem.key }}</li>
<ul>
<li *ngFor="let sectionItem of classItem.value | keyvalue; let i = index">
<h5> Section {{sectionItem.key}}</h5>
<ul>
<li><a href='#' *ngFor="let student of sectionItem.value ">{{student.name}}</a></li>
</ul>
</li>
</ul>
</ul>
</div>
public getStudents():可观察
更新的Stackblitz:步骤1:您将获得一个阵列,该阵列发射整个阵列,以便groupBy工作。您需要发射所有值,因此这里使用switchMap,我们将从中发射阵列的所有条目 步骤2:groupBy将给出另一个观察值,您需要将其合并以查看分组结果。所有组现在都将作为值发射 在下面的示例中,类3和5可以有两个组,因此subscribe函数中的最终结果将被调用两次,一次调用类3,另一次调用类5 第3步:如果您想更深入,请重复groupBy和mergeMap
this.http.get(this.studentURL).pipe(
switchMap(val => from(val)),
groupBy(studentList => studentList.class),
mergeMap(group => group.pipe(toArray())),
map(studentList => ({['class' + studentList[0].class]: studentList }))
)
闪电战:
更新2:解决方案 服务:
public getStudents(): Observable<any> {
return this.http.get<any[]>(this.studentURL)
.pipe(
switchMap(val => from(val)),
groupBy(studentList => studentList.class),
mergeMap(group => group.pipe(toArray())),
map(studentList => ({
[studentList[0].class]: studentList.reduce((sections, student) => ({...sections, [student.section]: [...(sections[student.section] || []), student]}), {})
})),
scan((response, studentList) => ({...response, ...studentList}), {})
);
}
students$: Observable<any>;
// you can hook up the observable here
// in template you can use the the async pipe
// to subscribe to the observable
ngOnInit() {
this.students$ = this.service.getStudents();
}
<div class='container'>
<ul *ngFor="let classItem of students$ | async | keyvalue; let i = index">
<li> Class {{ classItem.key }}</li>
<ul>
<li *ngFor="let sectionItem of classItem.value | keyvalue; let i = index">
<h5> Section {{sectionItem.key}}</h5>
<ul>
<li><a href='#' *ngFor="let student of sectionItem.value ">{{student.name}}</a></li>
</ul>
</li>
</ul>
</ul>
</div>
public getStudents():可观察
更新的Stackblitz:您在console.logI中看到的结果是什么?请看两件事:a)src/app/config/config.service.ts:16:5中出现错误-错误TS1128:需要声明或语句。16.点击(result=>result.json());b) 获取了另一个组件中的console.log中的json数据。您在console.logI中看到的结果是什么?请看两件事:a)src/app/config/config.service.ts:16:5中的错误-错误TS1128:预期的声明或语句。16.点击(result=>result.json());b) 获取了json数据,我在另一个组件中有console.log。您能提供一些解释吗。这将有助于理解您的解决方案。还有,我如何更深入地了解JSONY解决方案的工作原理。但我仍然需要将它们放在数组中,以便稍后在局部搜索中对其进行迭代。在浏览器控制台中获取此错误。错误:找不到类型为“object”的不同支持对象“[object]”。NgFor只支持绑定到数组之类的Iterables。您可以发布您的templatedone吗。我刚刚用component.ts和component.html文件code更新了帖子,没有手动订阅组件。这是推荐的方式。你能解释一下吗。这将有助于理解您的解决方案。还有,我如何更深入地了解JSONY解决方案的工作原理。但我仍然需要将它们放在数组中,以便稍后在局部搜索中对其进行迭代。在浏览器控制台中获取此错误。错误:找不到类型为“object”的不同支持对象“[object]”。NgFor只支持绑定到数组之类的Iterables。您可以发布您的templatedone吗。我刚刚用component.ts和component.html文件code更新了帖子,没有手动订阅组件。这是推荐的方法