Как я могу избежать использования * ngIf в шаблоне Angular? - PullRequest
0 голосов
/ 30 мая 2020

Я попытался использовать async / await, чтобы избежать *ngIf в шаблоне компонента.

Я получаю сообщение об ошибке в консоли Chrome при удалении *ngIf в шаблоне компонента.

Может кто поможет найти решение. Я не хочу использовать *ngIf в шаблоне компонента в качестве требования

Я вызываю GET REST API и использую подписку. Кроме того, я получаю результаты без ошибки, если использую *ngIf, но мне нужны те же результаты без использования *ngIf

CODE: 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>

Ответы [ 5 ]

0 голосов
/ 03 июня 2020

Спасибо, ребята, что пытались помочь мне разными способами. Но да, я не получил решения из ответов.

Наконец, я сам получил решение, проводя некоторые исследования и разработки по «избеганию * ngIf», и вкратце следующее решение:

Использование Angular службы «Resolver» I получил данные перед рендерингом шаблона / View.

0 голосов
/ 30 мая 2020

Код, который у вас есть для хранения 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.");
  }

Если вы хотите использовать обещания (но вы должны наблюдать в Angular), вы можете сделать он использует метод 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>
0 голосов
/ 30 мая 2020

Я думаю, что вы неправильно используете * ngIf. Все, что вам нужно сделать, это добавить * 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>
0 голосов
/ 30 мая 2020

Angular имеют систему жизненного цикла, поэтому Angular пытается загрузить компонент перед получением данных из вашего API. Итак, да, вам нужно обработать случай до того, как API ответит.

У вас есть 2 способа сделать это:

  • используйте * ngIf, но вам не нужно используйте * ngIf везде, если вы делаете много вызовов, если вы этого опасаетесь, вы можете правильно использовать ngrx и использовать один * ngIf только в своем HTML

  • инициализировать свои данные со значением по умолчанию. Angular загрузит вашего пользователя "по умолчанию" и заменит его пользователем, полученным API, если, конечно, нет ошибки. Если вы действительно хотите использовать это, попробуйте

user: user = new user();

и, конечно же, инициализировать все используемые вами атрибуты пустой строкой ... в конструкторе пользователя.

Но я думаю, что первый способ лучше, потому что вы можете более правильно обрабатывать ошибку и случай ожидания с помощью счетчика загрузки, загрузки и сообщения об ошибке, ... НО вам нужно изучить основы rx js:)

0 голосов
/ 30 мая 2020

Я думаю, вам нужно использовать ngIf, потому что ваш шаблон загружается до того, как он получит ваши данные. Итак, ваш HTML готов к получению данных. Что вы можете сделать, и это более чисто, - это создать логическую переменную:

isDataReady: Boolean = false;

Затем в вашем html просто используйте ее, потому что она всегда будет ложной, пока вы не измените ее в своем компоненте, когда подписка получает данные.

Кроме того, в своих проектах я использую прядильщик материалов angular, чтобы пользователь знал, что он загружает данные серверной части с этой переменной, которую я создал.

Надеюсь на это помогает!

...