Отобразить счетчик до ответа API в угловых 6 - PullRequest
0 голосов
/ 16 сентября 2018

Я новичок в Angular 6, и у меня нет опыта работы с какой-либо версией Angular ранее, и я создаю свой сайт с использованием Angular 6, в котором мне нужно отображать счетчик до тех пор, пока не будет получен ответ API. Я использую httpclient из угловой 6 для вызова API. Я хочу показать счетчик для каждого запроса API. Я искал на SO, но не нашел ответа на свой вопрос. Ниже приведен файл компонентов и служб.

/* data.services.ts */

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})

export class DataService {
  constructor(private http: HttpClient) { }
  getUsers() {
    return this.http.get('https://jsonplaceholder.typicode.com/users')
  } 
}

/* users.component.ts *

import { Component, OnInit } from '@angular/core';
import {DataService} from '../data.service';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.css']
 })

export class UsersComponent implements OnInit {
  users$: Object;
  constructor(private data: DataService) { }
  ngOnInit() {
    this.data.getUsers().subscribe(data => {
      this.users$ = data; 
    });
  }
}

Примечание: я не хочу использовать какой-либо пакет или модуль для этого.

Может кто-нибудь помочь мне решить эту проблему? Любая помощь будет оценена.

Ответы [ 5 ]

0 голосов
/ 15 мая 2019

Вы можете сохранить ссылку на подписку как свойство компонента пользователя, а затем использовать простой * ngIf в своем шаблоне, чтобы показать / скрыть индикатор загрузки:

/* users.component.ts *

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';
import { Observable, Subscription } from 'rxjs';

@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
  users$: Object;
  subscription: Subscription

  constructor(private data: DataService) { }

  ngOnInit() {
    this.subscription = this.data.getUsers().subscribe(data => {
      this.users$ = data; 
    });
  }
}

В вашем шаблоне:

...
<div *ngIf="!subscription?.closed">loading...</div>
...

См. http://reactivex.io/rxjs/class/es6/Subscription.js~Subscription.html для получения дополнительной информации о классе подписки.

Это выходит за рамки этого вопроса, но вы также должны убедиться, что ваша подписка закрыта, когда ваш компонент уничтожен (поэтому может помочь сохранение ссылки на подписку): например, вызовите subscription.unsubscribe (), если необходимо, в ngOnDestroy (), или расширить базовый класс для этой цели (чтобы все ваши компоненты могли извлечь из этого пользу).

См. https://brianflove.com/2016/12/11/anguar-2-unsubscribe-observables/ или https://netbasal.com/automagically-unsubscribe-in-angular-4487e9853a88

0 голосов
/ 16 сентября 2018

Для этой цели я бы использовал http-перехватчик для проверки определенных событий во время http-запроса. Давайте возьмем компонент, который будет иметь некоторый загрузчик, и поместим этот компонент на тот же уровень, что и на выходе маршрутизатора или на компонент приложения. От нашего перехватчика мы свяжемся со службой, чтобы сообщить нашему компоненту, когда показывать загрузчик или нет.

Для этого есть простой угловой пример 6: https://stackblitz.com/edit/angular-hgxcsu

0 голосов
/ 16 сентября 2018

Посмотрите на мой пакет ngx-RxCache. Работа с загрузкой является одним из ключевых вариантов использования. Установите ngx-rxcache. Не подписывайтесь на наблюдаемые в вашем TypeScript, используйте асинхронный канал в вашем представлении. Проверьте демо на https://stackblitz.com/edit/angular-3yqpfe

Получите анимацию загрузки из https://loading.io/, чтобы поместить ее в раздел загрузки HTML

/* data.services.ts */

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { RxCacheService } from 'ngx-rxcache';
import { User } from 'path to user interface definition';

@Injectable({
  providedIn: 'root'
})

export class DataService {
  constructor(private http: HttpClient, private cache: RxCacheService) { }
  load() {
    this.usersCacheItem.load();
  }

  private usersCacheItem = this.cache.get<User[]>({
      id: '[User] users',
      construct: () => this.http.get<User[]>('https://jsonplaceholder.typicode.com/users')
    });

    users$ = this.usersCacheItem.value$;
    loading$ = this.usersCacheItem.loading$;
}

/* users.component.ts *

import { Component, OnInit } from '@angular/core';
import {DataService} from '../data.service';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.css']
 })

export class UsersComponent implements OnInit {
  users$: this.data.users$;
  loading$: this.data.loading$;
  constructor(private data: DataService) {
    data.load();
  }
}
<div *ngIf="loading$ | async; else loaded">
    loading ...
</div>

<ng-template #loaded>
    <div *ngFor="let user of users$ | async">{{item}}</div>
</ng-template>
0 голосов
/ 16 сентября 2018

Если вы настаиваете на том, чтобы не устанавливать какие-либо пакеты, используйте логический флаг, чтобы узнать, завершена ли загрузка еще

Получите анимацию загрузки из https://loading.io/, чтобы поместить ее в раздел загрузки HTML

/* data.services.ts */

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})

export class DataService {
  constructor(private http: HttpClient) { }
  getUsers() {
    return this.http.get('https://jsonplaceholder.typicode.com/users')
  } 
}

/* users.component.ts *

import { Component, OnInit } from '@angular/core';
import {DataService} from '../data.service';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.css']
 })

export class UsersComponent implements OnInit {
  users: Object; // <-- Do not use $ at the end of a variable unless it is an observable
  loading = true;
  constructor(private data: DataService) { }
  ngOnInit() {

    this.data.getUsers().subscribe(data => {
      this.users = data;
      this.loading = false;
    });
  }
}

<div *ngIf="loading else loaded">
    loading ...
</div>

<ng-template #loaded>
    <div *ngFor="let user of users">{{user.name}}</div>
</ng-template>
0 голосов
/ 16 сентября 2018

Вы можете использовать ng4-loading-spinner

Выполнить npm i ng4-loading-spinner --save

Модуль импорта в корневой модуль вашего приложения

import { Ng4LoadingSpinnerModule } from 'ng4-loading-spinner';

Сделать запись импорта

 imports: [ Ng4LoadingSpinnerModule.forRoot() ]

Включите спиннер в свой корневой компонент.

<ng4-loading-spinner> </ng4-loading-spinner>

использовать show() и hide() внутри subscribe обратный вызов

   import { Ng4LoadingSpinnerService } from 'ng4-loading-spinner';
     constructor(
            private spinnerService: Ng4LoadingSpinnerService,
            private data: DataService
        ) { }
       ngOnInit() {
         this.spinnerService.show();//show the spinner
    this.data.getUsers().subscribe(data => {
      this.users$ = data; 
       this.spinnerService.hide();//hide the spinner if success
    },
    (error)=>this.spinnerService.hide();//hide the spinner in case of error
 );
  }}

Live Demo

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