如何避免在 Angular 模板中使用 *ngIf?
How can I avoid using *ngIf in an Angular template?
我尝试使用 async/await 来避免在组件模板中使用 *ngIf
。
当我在组件模板中删除 *ngIf
时,Chrome 控制台出现错误。
任何人都可以帮助获得解决方案。我不想在组件模板中使用 *ngIf
作为要求
我正在调用 GET REST API 并使用订阅。另外,如果我使用 *ngIf
,我会得到没有错误的结果,但我想要在不使用 *ngIf
的情况下得到相同的结果
代码:
component.ts
export class DisplayComponent implements OnInit {
users : user[];
user: user;
userResult: any;
constructor(private http: HttpClient) { }
ngOnInit() {
}
async readUser(id){
this.userResult = await this.http.get<user>("http://localhost:8090/user/" +id).subscribe(
data => {
this.user = data;
},
error =>{
return console.error();
;
}
)
console.log("Fuuhhh! Client will wait till promise is resolved.");
}
}
代码: DisplayComponent.html
<div style="text-align: center;">
<button (click)="loadUsers()">load Users</button>
<table style="margin: 0 auto;" border="1">
<tr>
<th>Identity</th>
</tr>
<tr *ngFor="let user of users">
<td>
<button style="background: transparent;border: transparent;cursor: pointer;" (click)="readUser(user.id)">{{user?.id}}</button>
</td>
</tr>
</table>
</div>
<div style="text-align: center;">
<span style="color: darkgray;">Identity:</span> <span style="color: gray;">{{user.id}}</span> <br>
<span>Name:</span> {{user.name}} <br>
<span>School:</span> {{user.school}} <br>
</div>
我认为您必须使用 ngIf,因为您的模板会在获取数据之前加载。
因此,您的 HTML 已准备好获取数据。你可以做的,而且更干净,是创建一个布尔变量:
isDataReady: Boolean = false;
然后在您的 html 中使用它,因为它始终为假,直到您在订阅获取数据时在组件中更改它。
此外,在我的项目中,我使用了一个 angular material 微调器,让用户知道它使用我创建的这个变量加载后端数据。
希望对您有所帮助!
我认为你没有正确使用 *ngIf way.All 你需要做的是在你的模板中添加一个 *ngIf,如下所示,你不需要为每个标签添加多个 *ngIf。
<div style="text-align: center;" *ngIf="user">
<span style="color: darkgray;">Identity:</span> <span style="color: gray;">{{user.id}}</span> <br>
<span>Name:</span> {{user.name}} <br>
<span>School:</span> {{user.school}} <br>
</div>
Angular 有一个生命周期系统,所以 Angular 试图在从你的 API 获取数据之前加载组件。所以是的,您需要在 API 回复之前处理此案。
您有 2 种方法可以做到这一点:
使用*ngIf,但如果你打了很多电话,你不必到处都使用*ngIf,如果你害怕,你可以正确使用ngrx,只在你的[=中使用一个*ngIf 36=]
使用默认值初始化您的数据。 Angular 将载入您的 "default" 用户并将其替换为 API 接收到的用户,当然前提是没有错误。如果您真的想使用它,请尝试
user: user = new user();
当然,在用户构造函数中通过空字符串初始化您正在使用的所有属性。
但我认为第一种方法更好,因为您可以使用加载微调器、加载和错误消息更正确地处理错误和等待情况,...但是您需要学习 rxjs 的基础知识 :)
您用于存储 userResult 的代码不是承诺,而是订阅:
async readUser(id){
// this block is wrong, userResult is a subscription
this.userResult = await this.http.get<user>("http://localhost:8090/user/" +id).subscribe(
data => {
this.user = data;
},
error =>{
return console.error();
;
}
)
console.log("Fuuhhh! Client will wait till promise is resolved.");
}
如果你想使用 promises(但你应该在 Angular 中使用 observables),你可以使用 toPromise()
方法,如下所示:
async readUser(id){
try {
this.userResult = await this.http.get<user>("http://localhost:8090/user/" +id).toPromise();
this.user = this.userResult // if you really want an extra step here
} catch(error) {
console.log(error);
}
}
关于你的问题,在这种情况下你应该使用*ngIf
。
对于代码块,将它与 ng-container
一起使用,如下所示:
<ng-container *ngIf="user">
.....
</ng-container>
谢谢大家尝试以不同的方式帮助我。但是,是的,我没有从答案中得到解决方案。
最后,我自己在"avoiding *ngIf"上做了一些研发得到了解决方案,以下是简略的解决方案:
使用 Angular "Resolver" 服务我在渲染 template/View.
之前获取了数据
我尝试使用 async/await 来避免在组件模板中使用 *ngIf
。
当我在组件模板中删除 *ngIf
时,Chrome 控制台出现错误。
任何人都可以帮助获得解决方案。我不想在组件模板中使用 *ngIf
作为要求
我正在调用 GET REST API 并使用订阅。另外,如果我使用 *ngIf
,我会得到没有错误的结果,但我想要在不使用 *ngIf
代码: component.ts
export class DisplayComponent implements OnInit {
users : user[];
user: user;
userResult: any;
constructor(private http: HttpClient) { }
ngOnInit() {
}
async readUser(id){
this.userResult = await this.http.get<user>("http://localhost:8090/user/" +id).subscribe(
data => {
this.user = data;
},
error =>{
return console.error();
;
}
)
console.log("Fuuhhh! Client will wait till promise is resolved.");
}
}
代码: DisplayComponent.html
<div style="text-align: center;">
<button (click)="loadUsers()">load Users</button>
<table style="margin: 0 auto;" border="1">
<tr>
<th>Identity</th>
</tr>
<tr *ngFor="let user of users">
<td>
<button style="background: transparent;border: transparent;cursor: pointer;" (click)="readUser(user.id)">{{user?.id}}</button>
</td>
</tr>
</table>
</div>
<div style="text-align: center;">
<span style="color: darkgray;">Identity:</span> <span style="color: gray;">{{user.id}}</span> <br>
<span>Name:</span> {{user.name}} <br>
<span>School:</span> {{user.school}} <br>
</div>
我认为您必须使用 ngIf,因为您的模板会在获取数据之前加载。 因此,您的 HTML 已准备好获取数据。你可以做的,而且更干净,是创建一个布尔变量:
isDataReady: Boolean = false;
然后在您的 html 中使用它,因为它始终为假,直到您在订阅获取数据时在组件中更改它。
此外,在我的项目中,我使用了一个 angular material 微调器,让用户知道它使用我创建的这个变量加载后端数据。
希望对您有所帮助!
我认为你没有正确使用 *ngIf way.All 你需要做的是在你的模板中添加一个 *ngIf,如下所示,你不需要为每个标签添加多个 *ngIf。
<div style="text-align: center;" *ngIf="user">
<span style="color: darkgray;">Identity:</span> <span style="color: gray;">{{user.id}}</span> <br>
<span>Name:</span> {{user.name}} <br>
<span>School:</span> {{user.school}} <br>
</div>
Angular 有一个生命周期系统,所以 Angular 试图在从你的 API 获取数据之前加载组件。所以是的,您需要在 API 回复之前处理此案。
您有 2 种方法可以做到这一点:
使用*ngIf,但如果你打了很多电话,你不必到处都使用*ngIf,如果你害怕,你可以正确使用ngrx,只在你的[=中使用一个*ngIf 36=]
使用默认值初始化您的数据。 Angular 将载入您的 "default" 用户并将其替换为 API 接收到的用户,当然前提是没有错误。如果您真的想使用它,请尝试
user: user = new user();
当然,在用户构造函数中通过空字符串初始化您正在使用的所有属性。
但我认为第一种方法更好,因为您可以使用加载微调器、加载和错误消息更正确地处理错误和等待情况,...但是您需要学习 rxjs 的基础知识 :)
您用于存储 userResult 的代码不是承诺,而是订阅:
async readUser(id){
// this block is wrong, userResult is a subscription
this.userResult = await this.http.get<user>("http://localhost:8090/user/" +id).subscribe(
data => {
this.user = data;
},
error =>{
return console.error();
;
}
)
console.log("Fuuhhh! Client will wait till promise is resolved.");
}
如果你想使用 promises(但你应该在 Angular 中使用 observables),你可以使用 toPromise()
方法,如下所示:
async readUser(id){
try {
this.userResult = await this.http.get<user>("http://localhost:8090/user/" +id).toPromise();
this.user = this.userResult // if you really want an extra step here
} catch(error) {
console.log(error);
}
}
关于你的问题,在这种情况下你应该使用*ngIf
。
对于代码块,将它与 ng-container
一起使用,如下所示:
<ng-container *ngIf="user">
.....
</ng-container>
谢谢大家尝试以不同的方式帮助我。但是,是的,我没有从答案中得到解决方案。
最后,我自己在"avoiding *ngIf"上做了一些研发得到了解决方案,以下是简略的解决方案:
使用 Angular "Resolver" 服务我在渲染 template/View.
之前获取了数据