gpt4 book ai didi

angular - ngOnInit 中的属性集导致 "type error: this.student is undefined"

转载 作者:搜寻专家 更新时间:2023-10-30 22:03:35 24 4
gpt4 key购买 nike

编辑:我在此处发布的代码与我最初编写的代码一样运行良好。我的学生界面中有一个愚蠢的拼写错误,因此每个学生对象的值“ID”始终未定义。我很生气,我花了好几天才意识到这一点。谢谢大家的回答。

我目前正在学习 Angular,但在组件的 OnInit 方法中设置属性时遇到了问题。我正在使用服务组件从 json 文件中获取数据并将其分配给名为“student”的自定义接口(interface)的实例。

当以数组形式抓取所有学生数据以显示在表格中时,一切正常。但是,当试图仅获取一名学生的信息以显示在“详细信息”模板上时,我收到“类型错误:_co.student 未定义”。

将“*ngIf='student'”添加到模板会消除错误消息,但不会填充模板。

这里是抓取服务组件中定义的数据的函数

private studentURL = 'assets/college-apps.json';

constructor(private http: HttpClient){}

getStudents(): Observable<Student[]> {
return this.http.get<Student[]>(this.studentURL);
}

getStudent(id: number): Observable<Student> {
return this.getStudents().pipe(map(students => students.find(student => student.ID === id)));
}

这是学生详细信息组件中的 ngOnInit 方法

student: Student;

constructor(private route: ActivatedRoute, private router: Router, private studentService: StudentService) {}

ngOnInit() {
let id = +this.route.snapshot.paramMap.get('id');

this.studentService.getStudent(id).subscribe(
student => this.student = student
)
}

这是模板

<mat-card *ngIf='student'>
<mat-card-title>{{student.firstName}} {{student.lastName}}'s Details</mat-card-title>

<mat-card-content let stude>First Name: {{student.firstName}} </mat-card-content>
<mat-card-content>Last Name: {{student.lastName}} </mat-card-content>
<mat-card-content>High School: {{student.highSchool}} </mat-card-content>
<mat-card-content>GPA: {{student.gpa}} </mat-card-content>
<mat-card-content>Reading SAT Score: {{student.readingSatScore}} </mat-card-content>
<mat-card-content>Math SAT Score: {{student.mathSatScore}} </mat-card-content>

<a mat-stroked-button [routerLink]="['']">Back</a>
</mat-card>

最佳答案

因为 this.student 是在模板首次呈现时在异步回调(在订阅中)中分配的 this.student 未定义。当 http 调用返回一个值时,它是 this.student 获取一个值,直到那时当 angular 尝试渲染模板时它会产生未定义的错误。为了解决这种情况,angular 拥有一个名为 safe navigation operator 的运算符.

The Angular safe navigation operator, ?, guards against null and undefined values in property paths in templates.

<mat-card>
<mat-card-title>{{student?.firstName}} {{student?.lastName}}'s Details</mat-card-title>

<mat-card-content>First Name: {{student?.firstName}} </mat-card-content>
<mat-card-content>Last Name: {{student?.lastName}} </mat-card-content>
<mat-card-content>High School: {{student?.highSchool}} </mat-card-content>
<mat-card-content>GPA: {{student?.gpa}} </mat-card-content>
<mat-card-content>Reading SAT Score: {{student?.readingSatScore}} </mat-card-content>
<mat-card-content>Math SAT Score: {{student?.mathSatScore}} </mat-card-content>

<a mat-stroked-button [routerLink]="['']">Back</a>
</mat-card>

这里是概念的简单演示 https://stackblitz.com/edit/angular-gem5sk

尝试删除模板中的 ? 之一,您将在控制台中看到未定义的错误。

还请注意,在 http 调用完成并将值分配给 this.student 之前,模板中的相关位置将为空,这可能是糟糕的用户体验,尤其是对于持续时间长的 http 调用。为此,应用程序中必须包含某种加载程序机制,但这与这个问题有很大关系。写在这里只是为了补充信息。

还放置带有异步 block 的 console.log 以正确查看是否从 http 调用返回值

ngOnInit() {
let id = +this.route.snapshot.paramMap.get('id');

this.studentService.getStudent(id).subscribe(student => {
this.student = student
console.log(this.student); // prints when the request completes
});
console.log(this.student); // always prints undefined, and gets printed before above console.log
}

关于angular - ngOnInit 中的属性集导致 "type error: this.student is undefined",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56908854/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com