Повторное использование асинхронного канала (наблюдаемый) - PullRequest
0 голосов
/ 29 октября 2018

Я пытаюсь использовать канал async для отображения таблицы в Angular, но получаю сообщение об ошибке: "... Невозможно найти отличающийся вспомогательный объект '[object Object]' типа 'object'. NgFor поддерживает только привязку к итерациям, таким как массивы. "

Мой код:

<div *ngIf="studentList | async; else loading">
  <table>
    <tr>
      <th>ID</th>
      <th>First Name</th>
      <th>Last Name</th>
    </tr>
    <tr *ngFor="let student of studentList">
      <td>{{student.id}}</td>
      <td>{{student.first_name}}</td>
      <td>{{student.last_name}}</td>
    </tr>
  </table>
  {{studentList | json}}
</div>

<ng-template #loading>
  <div>Loading ...</div>
</ng-template>

Сервер возвращает Observable<Student[]>

Если я заменим ngFor на приведенное ниже, это сработает, но это означает, что будут сделаны два HTTP.get вызова, которые мне не нужны:

<tr *ngFor="let student of (studentList | async)">

Можно ли мне повторно использовать значение studentList из ngIf в ngFor, сделав таким образом только один запрос к моему бэкэнду?

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Помимо удивительного и простого ответа @ibenjelloun, я также хотел добавить еще один подход, используя templateOutlet

Передайте оцененный Observable в ng-template и используйте шаблон по templateOutlet. У вас может быть что-то подобное в вашем шаблоне:

<ng-container
    *ngTemplateOutlet="asyncTemplate;context:{listEvaluated: studentList | async}">
</ng-container>


<ng-template #asyncTemplate let-inputList="listEvaluated">
    <div *ngIf="inputList; else loading">
      <table>
        <tr>
          <th>ID</th>
          <th>First Name</th>
          <th>Last Name</th>
        </tr>
        <tr *ngFor="let student of inputList">
          <td>{{student.id}}</td>
          <td>{{student.first_name}}</td>
          <td>{{student.last_name}}</td>
        </tr>
      </table>
    </div>
</ng-template>

Обратите внимание: оператор | pipe в объекте context работает как конвейер, а не как побитовый оператор.

0 голосов
/ 29 октября 2018

Хорошей практикой является именование наблюдаемых с помощью суффикса $, скажем, studentList$ имеет тип Observable<Student[]>. Вы можете использовать async с as, чтобы получить studentList типа Student[]:

<div *ngIf="studentList$ | async as studentList; else loading">
  <table>
    <tr>
      <th>ID</th>
      <th>First Name</th>
      <th>Last Name</th>
    </tr>
    <tr *ngFor="let student of studentList">
      <td>{{student.id}}</td>
      <td>{{student.first_name}}</td>
      <td>{{student.last_name}}</td>
    </tr>
  </table>
</div>
...