在处理请求时挂断应用程序

时间:2019-02-03 08:59:06

标签: angular typescript async-await request

有一个问题,为什么在发送GET请求时应用程序挂起?如何解决?

我知道这是异步的,但我不知道该怎么办。

也就是说,当发送GET请求时,网站完全挂起1-2秒。

articles.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>

articles.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 :(得分:0)

更好的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 });
        }
      );
  }

  ...
}
  

这是您推荐的Working Sample StackBlitz