Angular 如何过滤rxjs数据流中的数组?
我正在尝试基于songId在song-details.component.ts中显示评论。我在review.service.ts中编写了一些代码,它根据songId过滤数据。但是代码不起作用。它仍然显示每首歌曲下的所有歌曲评论。请引导我 以下是song-list.component.tsAngular 如何过滤rxjs数据流中的数组?,angular,rxjs,Angular,Rxjs,我正在尝试基于songId在song-details.component.ts中显示评论。我在review.service.ts中编写了一些代码,它根据songId过滤数据。但是代码不起作用。它仍然显示每首歌曲下的所有歌曲评论。请引导我 以下是song-list.component.ts import { Component, OnInit } from '@angular/core'; import {SongListService} from '../song-list.service';
import { Component, OnInit } from '@angular/core';
import {SongListService} from '../song-list.service';
@Component({
selector: 'app-song-list',
templateUrl: './song-list.component.html',
styleUrls: ['./song-list.component.css']
})
export class SongListComponent implements OnInit {
public songList: Array<any>;
searchTerm: string;
constructor(private songListService: SongListService) {}
ngOnInit(): void {
this.songListService.retrieveAllSongs().subscribe((data: any) => this.songList = data);}
}
import { Component, OnInit } from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {SongListService} from '../song-list.service';
import {ReviewService} from '../review.service';
@Component({
selector: 'app-song-details',
templateUrl: './song-details.component.html',
styleUrls: ['./song-details.component.css']
})
export class SongDetailsComponent implements OnInit {
songs: any;
reviews: any;
constructor(private route: ActivatedRoute, private songListService: SongListService
private reviewService: ReviewService) { };
ngOnInit(): void {
this.route.paramMap.subscribe(params => {
console.log(params.get('id'))
this.songListService.retrieveSongsById(params.get('id')).subscribe(s =>{
console.log(s);
this.songs = s;
})
});
this.route.paramMap.subscribe(params => {
console.log(params.get('id'))
this.reviewService.retrieveReviewsBySongId(params.get('id')).subscribe(r =>{
console.log(r);
this.reviews = r;
})
})
export class AppComponent implements OnInit {
constructor(private reviewService: ReviewService) {}
reviews: Review[] = [];
ngOnInit() {
this.reviewService.retrieveReviewsBySongId(1).then(reviews => {
this.reviews = reviews;
});
}
}
以下是review.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders} from '@angular/common/http';
import { tap} from "rxjs/operators";
@Injectable({
providedIn: 'root'
})
export class ReviewService {
private headers: HttpHeaders;
private accessPointUrl: string = 'https://localhost:44355/api/reviews';
constructor(private http: HttpClient) {
this.headers = new HttpHeaders({ 'Content-Type': 'application/json; charset=utf-8'});
}
public retrieveReviews(){
return this.http.get(this.accessPointUrl, {headers: this.headers});
}
public retrieveReviewsBySongId(songId){
return this.http.get(this.accessPointUrl, {headers: this.headers})
.pipe(tap((data:any) => data.filter((d:any)=> d.songID == songId)));
}
import { HttpClient } from "@angular/common/http";
import { Inject, Injectable } from "@angular/core";
import { Review } from "../entities/review";
@Injectable({
providedIn: "root"
})
export class ReviewService {
constructor(
private httpClient: HttpClient,
@Inject("BASE_URL") private baseUrl: string
) {}
public retrieveReviews() {
return this.httpClient.get<Review[]>(`${this.baseUrl}/api/reviews`, {
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}).toPromise();
}
public retrieveReviewsBySongId(songId: number) {
return this.retrieveReviews()
.then((revs) => revs.filter((rev) => rev.songID === songId));
}
}
我真的不喜欢
管道
和点击
命令。我知道他们都在网上,但我建议尽量避开他们
我在这里创建了一个StackBlitz:
src/app/entities/review.ts
export class Review {
id: number;
songID: number;
username: string;
reviews: string;
ratings: number;
}
src/app/services/review.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders} from '@angular/common/http';
import { tap} from "rxjs/operators";
@Injectable({
providedIn: 'root'
})
export class ReviewService {
private headers: HttpHeaders;
private accessPointUrl: string = 'https://localhost:44355/api/reviews';
constructor(private http: HttpClient) {
this.headers = new HttpHeaders({ 'Content-Type': 'application/json; charset=utf-8'});
}
public retrieveReviews(){
return this.http.get(this.accessPointUrl, {headers: this.headers});
}
public retrieveReviewsBySongId(songId){
return this.http.get(this.accessPointUrl, {headers: this.headers})
.pipe(tap((data:any) => data.filter((d:any)=> d.songID == songId)));
}
import { HttpClient } from "@angular/common/http";
import { Inject, Injectable } from "@angular/core";
import { Review } from "../entities/review";
@Injectable({
providedIn: "root"
})
export class ReviewService {
constructor(
private httpClient: HttpClient,
@Inject("BASE_URL") private baseUrl: string
) {}
public retrieveReviews() {
return this.httpClient.get<Review[]>(`${this.baseUrl}/api/reviews`, {
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}).toPromise();
}
public retrieveReviewsBySongId(songId: number) {
return this.retrieveReviews()
.then((revs) => revs.filter((rev) => rev.songID === songId));
}
}
我获取评论的地方(app.component.ts)
显示评论(app.component.html)
身份证件
使用者
松吉德
评级
评论
{{review.id}
{{review.username}
{{review.songID}
{{review.ratings}}
{{review.reviews}}
我怀疑您的
评论中出现了问题。服务
,因此我建议将其修改为我发布的服务。点击操作符只会执行一个操作(“做这个和那个”),但不会在更改或操纵流的上下文中转换或做任何事情。
用map
操作符替换tap
操作符。
使用map,您将能够转换数据和map,并将其作为过滤数组而不是原始数组返回
进一步阅读:
为什么要订阅两次
paramMap
?我将两个代码块放在同一个处理程序中。你能确认你的api返回了正确的评论吗?在webbrowser-F12-Network选项卡-filterforxhr(ajax调用)中,发布您从APIs获得的响应的屏幕截图。第一个paramMap检索歌曲详细信息,第二个paramMap检索评论。我已经添加了响应的屏幕截图。请看一看,非常感谢。您的解决方案非常有效,如果解决了,您可以将答案标记为已接受答案。另一件事,我看到您正在为subscribe中的组件分配值,您可能想了解angular中的async
管道,它将简化您的代码。
public retrieveReviewsBySongId(songId){
return this.http.get(this.accessPointUrl, {headers: this.headers})
.pipe(map((data:any) => data.filter((d:any)=> d.songID == songId)));
}