如何避免在 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.

之前获取了数据