在组件ngOnInit
方法中使用 Angular 中的路由,我通过可观察性获得流派 ID,在该可观察量中,我调用了一个带有发出 HTTP 请求的服务的方法。
this.movies: Movie[];
ngOnInit() {
this.route.paramMap.subscribe(param => {
let id = +param.get('id');
this.movieService.getMoviesByGenres(id).subscribe( response => {
this.movies = response['results'];
});
});
}
它返回以下内容:
"results": [
{
"vote_count": 664,
"id": 287947,
"video": false,
"vote_average": 7.4,
"title": "Shazam!",
.
.
.
},
{
"vote_count": 3623,
"id": 299537,
"video": false,
"vote_average": 7.2,
"title": "Captain Marvel",
.
.
.
}, ...
]
它返回的是没有强制转换的电影,因此我需要通过为第一个请求返回的每个电影调用另一个 HTTP 请求来请求电影的转换,并将转换的第二个请求信息推送到 movies[i].cast
数组。
所以基本上我想要的,看起来像这样:
ngOnInit() {
this.route.paramMap.subscribe(param => {
let id = +param.get('id');
this.movieService.getMoviesByGenres(id).subscribe( response => {
this.movies = response['results'];
});
//pesudo code
foreach(this.movies as movie) {
this.movies[current element].casts =
this.movieService.getCastByMovieId(movie.id);
}
});
}
按流派获取电影,当结果到达时,循环访问 movies[]
数组并调用该方法以按电影 ID 获取强制转换并将强制转换添加到电影casts: string []
属性。并返回现在也包含演员表的this.movies: Movies[]
。
当你在Angular中工作时,你也可以利用RxJS的强大功能来实现这一点,像这样的东西。
public ngOnInit(): void {
this.route.paramMap.subscribe(param => {
let id = +param.get('id');
this.movieService.getMoviesByGenres(id).pipe(
map(response => response['results']),
mergeMap((movies: any[]) => {
return forkJoin(
movies.map(movie => {
return this.movieService.getCastByMovieId(movie.id)
.pipe(
map((res: any) => {
movie.cast = res;
return movie;
})
);
})
)
}))
.subscribe(movies => {
// Your logic here
});
})
}
基本上,您首先获取电影,然后通过forkJoin管道传输结果,该forkJoin一起执行请求,保持顺序,将结果添加到movie.cast并在最后返回完整的数组。通过这种方式,您还可以知道执行何时完成。
请记住,如果 forkJoin 中的请求失败,则整个执行将失败,因此您应该专门针对每个请求处理错误。
你可以尝试这样的事情:
ngOnInit() {
const self= this;
this.route.paramMap.subscribe(param => {
let id = +param.get('id');
self.movieService.getMoviesByGenres(id).subscribe( response => {
self.movies = response['results'];
for(let movie of self.movies){
self.movieService.getCastByMovieId(movie.id).subscribe((result)=>{
self.movies[current element].casts = result;
});
}
});
});
}
我使用 self 作为变量,因为内部服务的上下文与组件不同。简而言之,"this"的唯一内容对于服务和组件是不同的。
注意:在你的电影服务中,让你返回HTTP请求,否则它不会返回可观察的,因此组件将无法订阅它。
我们可以通过发出端点请求来遍历数组,例如
在 Ts 文件中
let listToUpdate = [{...}, {...},...];
this.serviceObj.postData(listToUpdate).subscribe(
response => console.log(response),
error => console.error(error),
() => console.info("All requests done")
);
在服务文件中:
import { from } from "rxjs";
import { concatMap } from "rxjs/operators";
...
postData(listToUpdate){
return from(listToUpdate).pipe(
concatMap(payload => this.http.post('http://localhost:4200/billing/balance-statement', payload))
);
}