Зависает приложение при обработке запроса - PullRequest
0 голосов
/ 03 февраля 2019

Возник такой вопрос, почему при отправке GET-запроса приложение зависает?Как это исправить?

Я понимаю, что вещь асинхронная, но я не понимаю, что с ней делать.

То есть при отправке запроса GET сайт полностью зависаетв течение 1-2 секунд.

article.services.ts

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

export interface Article {
  title: string;
  collection: string[];
  description: string[];
  links: string[];
}

@Injectable({
  providedIn: 'root'
})

export class ArticlesService {
  constructor(private http: HttpClient) { }

  getArticles(url) {
    return this.http.get<Article>(url);
  }
}

search.component.ts

import { Component, OnInit } from '@angular/core';
import { Article, ArticlesService } from '../../services/articles.service';

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

export class SearchComponent implements OnInit {
  constructor(private articlesServices: ArticlesService) { }

  searchQuery: string;
  articles: {};

  static getUrl(searchQuery: string) {
    return 'https://ru.wikipedia.org/w/api.php?action=opensearch&profile=strict&search='
      + searchQuery + '&limit=100&namespace=0&format=json&origin=*';
  }

  showArticles() {
    this.articlesServices.getArticles(SearchComponent.getUrl(this.searchQuery))
      .subscribe(
        (data: Article) => this.articles = Object.values({ ...data })
      );
  }

  ngOnInit() {
  }
}

search.component.html

<div class="search-form mt-2 input-group mb-3">
  <input type="text" class="form-control search-input" placeholder="Поиск"
        [(ngModel)]="searchQuery"
        (keyup.enter)="showArticles();">
  <div class="input-group-append">
    <button (click)="showArticles()"
            class="btn btn-search btn-outline-secondary"
            type="submit">Search
    </button>
  </div>
</div>

<app-articles [articles]="articles">
</app-articles>

article.component.html

<div *ngIf="articles">
  <div class="ml-2">
    <h4>По запросу <small class="text-muted">"{{ articles[0] }}"</small>
      найдены статьи:</h4>
    <h6>Количество статей: {{ articles[1].length }}</h6>
  </div>
  <div class="article-block" *ngFor="let article of articles[1]; let i = index">
    <div *ngFor="let link of articles[3]; let k = index" [hidden]="i != k">
        <a class="link-article" [attr.href]="link">{{ article }}</a>
    </div>
    <div class="article-description" *ngFor="let description of articles[2]; let j = index" [hidden]="i != j">
      <div *ngIf="description !== ''; else missingSnippet">{{ description }}</div>
      <ng-template #missingSnippet>Not found</ng-template>
    </div>
  </div>
</div>

ОБНОВЛЕНИЕ :добавлены шаблоны компонентов

1 Ответ

0 голосов
/ 03 февраля 2019

Лучшим UX будет показывать пользователю сообщение Загрузка ... до тех пор, пока вы не получите результаты.Призрачная анимация в наши дни довольно распространена.

Но для простоты просто покажите пользователю сообщение о загрузке, пока статьи извлекаются из API.

Вам придется изменить свой шаблонвот так:

<div class="search-form mt-2 input-group mb-3">
  <input type="text" class="form-control search-input" placeholder="Поиск"
        [(ngModel)]="searchQuery"
        (keyup.enter)="showArticles();"
        (change)="showResults = false">
  <div class="input-group-append">
    <button (click)="showArticles()"
            class="btn btn-search btn-outline-secondary"
            type="submit">Search
    </button>
  </div>
</div>

<hr>

<div *ngIf="showResults">
  <app-articles *ngIf="articles; else elseCase" [articles]="articles">
  </app-articles>

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

И ваш класс компонентов вот так:

...

export class SearchComponent implements OnInit {
  ...
  showResults = false;

  searchQuery: string;
  articles: any[];

  static getUrl(searchQuery: string) {
    return 'https://ru.wikipedia.org/w/api.php?action=opensearch&profile=strict&search='
      + searchQuery + '&limit=100&namespace=0&format=json&origin=*';
  }

  showArticles() {
    this.showResults = true;
    this.articlesServices.getArticles(SearchComponent.getUrl(this.searchQuery))
      .subscribe(
        (data: Article) => { 
          this.articles = Object.values({ ...data });
        }
      );
  }

  ...
}

Вот вам Рабочий образец StackBlitz для вашегоссылка

...