抱歉,如果重復我試圖解決問題,但我不知道該怎么做
我正在嘗試建立一個流媒體網站(電影,系列,..等)
我有一個函式可以回傳節目的集數
我的 ts 組件代碼是:
export class MainCarouselComponent implements OnInit {
constructor(
private homeService: HomeService,
private episodeService: EpisodesService
) {}
MainCarousel?: IShow[];
EpisodesNum?: number;
ngOnInit(): void {
this.homeService.getHomeMainCarousel().subscribe((shows) => {
this.MainCarousel = shows;
this.MainCarousel.forEach(
(show) => (show.runtime = this.calculateRuntime(show))
);
});
}
calculateRuntime(_show: IShow): any {
if (_show.runtime > 0) {
var runtime = _show.runtime;
var hours = runtime / 60;
var rhours = Math.floor(hours);
var minutes = (hours - rhours) * 60;
var rminutes = Math.floor(minutes);
return `${rhours} hr ${rminutes} min`;
} else {
return this.calculateEpisodes(_show.id);
}
}
calculateEpisodes(_showId: number): number { //problem is here//
let episodesNum;
this.episodeService
.getEpisodes(_showId)
.subscribe((episodes) => (episodesNum = episodes.length));
return episodesNum;
}
}
我想回傳劇集的數量,但它回傳 undefiend,我知道它是異步的,所以它不會等待,但有人可以幫助我用正確的方法解決它嗎?
多謝 !
uj5u.com熱心網友回復:
您可以使用異步管道在 component.ts 中顯示這樣的值
public episodes$ = this.episodeService.getEpisodes(_showId);
在 component.html 中。
{{ (episodes$ | async)?.length }}
uj5u.com熱心網友回復:
這個是可以做到的,我們快速看一下這兩個問題:
您在calculateRuntime方法中混合了變數型別:
if (_show.runtime > 0) {
// calculations...
return `${rhours} hr ${rminutes} min`; // -> this returns a string
} else {
return this.calculateEpisodes(_show.id); // -> this returns undefined. observable, an "object"
}
現在,為什么回傳 undefined ?那是因為你的calculateEpisodes returns 未定義`:
calculateEpisodes(_showId: number): number { //problem is here//
// declare episodeNum; now it's undefined here
let episodesNum;
// call some service, whatever. It will go to network and do stuff later, but not yet.
this.episodeService
.getEpisodes(_showId)
.subscribe((episodes) => (episodesNum = episodes.length));
// Now return that `undefined` value
return episodesNum;
}
// after your method ended here, returning undefined, the browser will go to network to get that data, and set the value of the variable, but it is already too late.
那么如何解決呢?我們可以做多種方式,讓我們嘗試獲得一種“簡單”和“正確”的方式。
首先,Angular 說要將你的邏輯排除在組件之外,將所有這些代碼放在服務中。因此,讓我們嘗試創建一項服務:
@Injectable()
export class ShowsService {
constructor(
private homeService: HomeService,
private episodeService: EpisodeService
) {}
getShows(): Observable<Show[]> {
return this.homeService
.getShows()
.pipe(switchMap((shows) => this.calculateRuntimes(shows)));
}
calculateRuntimes(shows: Show[]): Observable<Show[]> {
return forkJoin(shows.map((show) => this.calculateRuntime(show)));
}
calculateRuntime(show: Show): Observable<Show> {
if (show.runtime > 0) {
return of(show);
} else {
return this.episodeService.getShowRuntime(show.id).pipe(
map((runtime) => ({
...show,
runtime,
}))
);
}
}
}
然后你將它注入你的MainCarouselComponent組件而不是其他兩個服務。
這是一個說明性示例。
uj5u.com熱心網友回復:
添加 setter 和 getter 函式將被重新激活:
_episodesNum=0;
set episodesNum(val){
this._episodesNum = val
}
get episodesNum(){
return this._episodesNum
}
calculateEpisodes(_showId: number): number { //problem is here//
let episodesNum;
this.episodeService
.getEpisodes(_showId)
.subscribe((episodes) => {
episodesNum = episodes.length
//new new
// set the new value and it will be reflected ractively to your template
this.episodesNum = episodesNum
});
// return episodesNum;
}
模板:
<div>
{{episodesNum}}
</div>
uj5u.com熱心網友回復:
我通過這樣做解決了它:
calculateRuntime(_show: IShow): any {
if (_show.runtime > 0) {
var runtime = _show.runtime;
var hours = runtime / 60;
var rhours = Math.floor(hours);
var minutes = (hours - rhours) * 60;
var rminutes = Math.floor(minutes);
return `${rhours} hr ${rminutes} min`;
} else {
this.episodeService
.getEpisodes(_show.id)
.subscribe(
(episodes) => (_show.runtime = episodes.length ' Episodes')
);
}
}
所以我在訂閱中將值設定為節目本身,不知道這是否是最好的方式,但很容易做到。
感謝所有試圖幫助我的人,我很感激。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/493803.html
