我毫不犹豫地问这个问题,因为我知道答案是非常明显的,让我盯着我看,但经过2天与代码的斗争后,我还要把头发拉出来。
我是棱角分明的新手(仅限FYI),但并不熟悉它背后的概念。我已经构建了一个小应用程序,它试图从托管在另一个服务器(可能)上的API读取数据,该服务器向我发回一个json对象。然后,此对象将填充组件。这是一些示例代码:
页面服务
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import { HttpErrorHandler, HandleError } from './http-error-handler.service';
import { AlcalaPage } from '../../shared/models/alcala-page.model';
import { environment } from '../../../environments/environment';
const httpOptions = {
headers: new HttpHeaders( {
'Content-Type': 'application/json'
})
};
@Injectable()
export class PageService {
pageServiceUrl: string;
private handleError: HandleError
constructor(private http: HttpClient, private httpErrorHandler: HttpErrorHandler) {
this.pageServiceUrl = environment.apiUrl + 'page/';
this.handleError = httpErrorHandler.createHandleError('PageService');
}
getPage(pageid: string): Observable<AlcalaPage> {
return this.http.get<AlcalaPage>(this.pageServiceUrl + pageid)
.pipe(
tap(data => console.log('Data is ' + data.months[0].expenses[0].entryType)),
catchError(this.handleError('getPage', null))
);
}
}
page.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { environment } from '../../../environments/environment';
import { AlcalaPage } from '../../shared/models/alcala-page.model';
import { PageService } from '../service/page.service';
@Component({
selector: 'app-page',
templateUrl: './page.component.html',
styleUrls: ['./page.component.scss']
})
export class PageComponent implements OnInit {
pageid: string;
imageurl: string;
dataModel: AlcalaPage;
public apiData;
constructor(private route: ActivatedRoute, private pageService: PageService) {
}
ngOnInit() {
this.route.params.subscribe(params => {
this.pageid = params['id'];
});
this.getPage();
this.imageurl = environment.imageUrl + this.pageid + '.jpg';
}
getPage(): void {
this.pageService.getPage(this.pageid)
.subscribe(
data => { this.dataModel = data; },
err => console.error(err),
() => console.log('page data loaded.')
);
}
}
page.component.html
<div class="container" fxLayout="row" fxLayout.xs="column" fxLayoutGap="0.5%" fxLayoutAlign="left">
<div fxFlex="70%">
<h2 class="right-align">{{dataModel.year}}</h2>
<mat-tab-group>
<mat-tab label="English">
<div *ngFor="let month of dataModel.months">
<app-month [dataModel]="month" currentLang="en"></app-month>
</div>
</mat-tab>
<mat-tab label="Spanish">
<div *ngFor="let month of dataModel.months">
<app-month [dataModel]="month" currentLang="es"></app-month>
</div>
</mat-tab>
</mat-tab-group>
</div>
<div fxFlex="20%">
<ngx-imageviewer [src]="this.imageurl"></ngx-imageviewer>
</div>
</div>
问题似乎源于页面的生命周期以及我(明显)对生命周期如何变化的误解。截至目前,页面上的年份字段正在加载(<h2 class="right-align">{{dataModel.year}}</h2>
),标签组正在显示它的标题(因此我看到&#34的标签;英语&#34;以及标签for&#34; Spanish&#34;但没有其他东西正在加载。当我检查控制台时,我看到一条错误消息,指出状态无法读取属性&#34;月份&#34;未定义。我发现这个错误消息令人困惑的两个原因:
我的猜测是a)我在标签中的* ngFor循环中做错了什么或b)我在页面生命周期中遗漏了一些东西。但是我不知道我可能做错了什么,因为我所遵循和看过的所有教程似乎都按照我实施的方式做事。任何对我可能做错的事情有任何想法的人都将不胜感激。
答案 0 :(得分:0)
它已加载异步,因此最初它将是未定义的。
请尝试执行let month of dataModel?.month
,只有在设置month
时才会显示dataModel
:https://angular.io/guide/template-syntax#the-safe-navigation-operator----and-null-property-paths