我正在使用自己正在构建的Angular 7应用程序,但是在从API返回数据并将其正确写入页面时遇到一些问题。
我尝试遵循有关Promise和Observable的指南,但是我似乎无法使数据正确显示在标题中,或者在这种情况下,无法使控制台停止抛出错误。我尝试使用Elvis运算符,但这只是使显示值空白而不是显示值。
resume.service.ts
export class ResumeService {
nameURL: string = 'REDACTED';
constructor(private http: HttpClient) { }
getName() {
return this.http.get(this.nameURL);
}
}
返回this.http.get(this.nameURL);
[
{
name: 'My Name'
}
]
navbar.component.ts
export class NavbarComponent implements OnInit {
data: Name;
reason = '';
@ViewChild('sidenav') sidenav: MatSidenav;
constructor(private http: HttpClient, private resumeAPI: ResumeService) {
this.resumeAPI.getName().subscribe(res => {
this.data = res[0];
});
}
close(reason: string) {
this.reason = reason;
this.sidenav.close();
}
}
export interface Name {
name: string
}
navbar.component.html
<div>
<a routerLink="/">
{{ this.data.name }}
</a>
</div>
因此,在导航栏中,我看到this(它显示了我的名字,模糊区域是该区域-API返回的数据)
但是,在控制台中,我看到以下errors (该链接包含控制台错误的图片,但这是细节: 无法读取未定义的属性“名称”
我知道在API提供渲染数据之前它会引发错误,但是我不确定如何解决它,因为将HTML更改为{{this.data?.name}}会使导航栏成为空白,{{this.data.name? }}导致此错误:表达式的意外结尾:{{this.data.name? }}
答案 0 :(得分:1)
删除HTML文件中的“ this”
{{ data.name }}
答案 1 :(得分:0)
在您的情况下,this.http.get()
执行异步操作。因此,在运行this.data = res[0];
行之前,this.data
尚未初始化,并且会引发错误。
您只需要检查this.data
是否通过
<a routerLink="/" *ngIf="this.data">
{{ this.data.name }}
</a>
或
<a routerLink="/">
{{ this.data?.name }}
</a>
但是我认为第一个更有意义,因为您可能不希望在设置链接文本之前显示链接
OR
您可以使用async
管道使Angular处理订阅本身。
this.data = this.resumeAPI.getName().pipe(map(res => res[0]));
在模板中
<a routerLink="/">
{{ (this.data | async).name }}
</a>
答案 2 :(得分:0)
此问题的解决方案是将Angular核心ChangeDetectorRef与detectChanges()一起使用。所有功劳归于 @MullisS
在TypeScript文件中,我们进行了更改:
import { Component, ViewChild } from '@angular/core';
至import { Component, ViewChild, ChangeDetectorRef } from '@angular/core';
(添加了ChangeDetectorRef)。
在构造函数中,我们进行了更改:
constructor(private resumeAPI: ResumeService) {
至constructor(private ref: ChangeDetectorRef, private resumeAPI: ResumeService) {
然后,在订阅功能中,我们进行了更改:
this.resumeAPI.getName().subscribe(res => {
this.data = res[0];
});
到
this.resumeAPI.getName().subscribe(res => {
this.data = res[0];
this.ref.detectChanges();
});
下面是完整的代码解决方案,以供参考: navbar.component.html
<a routerLink="/" >
{{ this.data?.name }}
</a>
navbar.component.html
import { Component, ViewChild, ChangeDetectorRef } from '@angular/core';
import { MatSidenav } from '@angular/material/sidenav';
import { HttpClient } from '@angular/common/http';
import { ResumeService } from '../services/resume.service';
@Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.scss'],
providers: [ResumeService]
})
export class NavbarComponent {
data: Name;
reason = '';
@ViewChild('sidenav') sidenav: MatSidenav;
constructor(private ref: ChangeDetectorRef, private resumeAPI: ResumeService) {
this.resumeAPI.getName().subscribe(res => {
this.data = res[0];
this.ref.detectChanges();
});
}
close(reason: string) {
this.reason = reason;
this.sidenav.close();
}
}
export interface Name {
name: string
}