Angular компонент при загрузке данных с сервера пуст на пару секунд - PullRequest
0 голосов
/ 06 августа 2020

Я создаю angular приложения с вызовами api с использованием httpclient, я не использую для этого никаких пакетов или плагинов, только httpclient.

Вот мой пример кода в service.ts

  getAdminMateriDetail(slug: any) {
    return this._http.get(this.apiURL + 'admin/material/' + slug).pipe(
      tap(console.log),
      shareReplay(1),
      tap(() => console.log('Materi Detail after sharing'))
    )
  }

Я пытаюсь получить подробную информацию о материалах с сервера, и в моем компоненте

getCurrentMateriDetail() {
    return this.userService.getAdminMateriDetail(this.slug).subscribe(
      (data:any) => {
        this.currentMateri = data.data;
      },
      error => {
        console.log(error);
      }
    )
  }

  ngOnInit() {
    this.getCurrentMateriDetail();
  }

я использую этот код на каждой странице, которая нуждается в данных с сервера, но я получаю неожиданный результат, поэтому, когда Я перехожу к компоненту, который вызывает api, и подписываюсь на этот api, мой компонент был пуст на пару секунд, иногда это быстро. Я новичок в использовании вызовов api, это нормально? или, может быть, я могу улучшить его, чтобы он работал быстрее, чтобы пользователь не видел «пустую страницу»?

Я также читал о кешировании, и я нашел shareReplay(1), поэтому я добавляю его в свой код, но все еще пустой на пару секунд. может кто-нибудь назвать мне причину?

Ответы [ 2 ]

1 голос
/ 06 августа 2020

Вызовы API всегда требуют времени. Итак, вам нужно создать загрузчик или что-то в этом роде. В шаблоне компонента вы можете сделать это с помощью ngIfElse:

<ng-container *ngIf="loadedData; else loader">
  page content
</ng-container>

<ng-template #loader>Loading...</loader>

shareReplay, используемого для обмена результатом "холодного" ( подробнее ), наблюдаемого между подписчиками. Но в вашем случае это бесполезно, потому что каждый вызов вашей функции создает новый Observable. Пример:

// Correct usage: 
const myMagicData$ = this._http.get(this.apiURL + 'admin/material/' + slug).pipe(
      tap(console.log),
      shareReplay(1),
      tap(() => console.log('Materi Detail after sharing'))
    );
    
myMagicData$.subscribe();
myMagicData$.subscribe();

В примере выше обе подписки дали одинаковый результат. Без shareReplay() каждая подписка запускает вызов API.

1 голос
/ 06 августа 2020

Это ожидаемое поведение, поскольку вы выполняете асинхронный c вызов:

this.userService.getAdminMateriDetail(this.slug).subscribe(
  (data:any) => {
    this.currentMateri = data.data;
  },
  error => {
    console.log(error);
  }
)

Здесь this.currentMateri имеет значение NULL, пока сервер не ответит (предположим, что он находится между 0,1se c и 1 секунда). Итак, в вашем HTML вам нужно обработать «что делать, когда this.currentMateri имеет значение null?»

Чтобы справиться с этим, добавьте *ngIf="currentMateri", где вы отображаете асинхронные данные, и добавьте другой тег (div , или что-то еще), когда *ngIf="!currentMateri", поэтому вы отобразите загрузчик или что-то еще ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...