一個(gè) Web 應(yīng)用通常會(huì)連接到遠(yuǎn)程服務(wù)器妻率,使用基于HTTP 協(xié)議的 API 對(duì)數(shù)據(jù)進(jìn)行操作不翩,如檢索、更新酸休、創(chuàng)建和刪除(CRUD)等。
本文通過(guò)一個(gè)實(shí)例來(lái)介紹如何在 Angular 應(yīng)用中訪問(wèn)遠(yuǎn)程的 API.
模擬遠(yuǎn)程 API
很多時(shí)候祷杈,我們沒(méi)有條件訪問(wèn)一個(gè)真正的后端 API 服務(wù)斑司。例如:
- 在創(chuàng)建一個(gè)快速原型的時(shí)候
- 可用的 API 服務(wù)還沒(méi)有交付
- 沒(méi)有 VPN,無(wú)法連接遠(yuǎn)程服務(wù)器
我們可以創(chuàng)建一個(gè)完全運(yùn)行在內(nèi)存的 API 服務(wù),模擬 Web 應(yīng)用所需要的 API 服務(wù)宿刮。
- 安裝必要的開發(fā)包互站。
npm install angular-in-memory-web-api@0.11.0 --save-dev
注意:angular-in-memory-web-api 的版本 0.11.0 適合于 Angular 10.
- 創(chuàng)建一個(gè) Angular 服務(wù),實(shí)現(xiàn)
InMemoryDbService interface
接口僵缺。
import { Injectable } from '@angular/core’;
import { InMemoryDbService } from "angular-in-memory-web-api”;
@Injectable({
providedIn: ‘root’
})
export class DataService implements InMemoryDbService {
constructor() { }
createDb() {
return {
books: [
{id: 1, name: '《三體》', price: 50.00},
{id: 2, name: '《黑暗森林》', price: 40.00},
{id: 3, name: '《死神永生》', price: 60.00},
{id: 4, name: '《超新星紀(jì)元》', price: 35.00}
]
}
}
}
Angular 服務(wù)必須實(shí)現(xiàn) InMemoryDbService
接口的 createDb
方法胡桃,該方法會(huì)創(chuàng)建一個(gè)內(nèi)存對(duì)象,表示一個(gè)數(shù)據(jù)庫(kù)磕潮。
- 導(dǎo)入
HttpClientInMemoryWebApiModule
模塊翠胰。
import { BrowserModule } from '@angular/platform-browser’;
import { NgModule } from '@angular/core’;
import { HttpClientInMemoryWebApiModule } from "angular-in-memory-web-api”;
import { AppComponent } from './app.component’;
import { DataService } from "./data.service”;
import { BooksModule } from './books/books.module’;
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientInMemoryWebApiModule.forRoot(DataService),
BooksModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
與導(dǎo)入 BrowserModule
模塊不同,我們使用了 forRoot
方法自脯,把 DataService
作為參數(shù)傳入之景,這樣可以確保只創(chuàng)建單一實(shí)例。
訪問(wèn)遠(yuǎn)程 API
接下來(lái)膏潮,我們使用 Angular 框架的內(nèi)置 HTTP 客戶端訪問(wèn)數(shù)據(jù)服務(wù)锻狗。
- 在
AppModule
模塊中導(dǎo)入HttpClientModule
模塊,使用HttpClientModule
模塊中的服務(wù)處理異步的 HTTP 通信焕参。
import { BrowserModule } from '@angular/platform-browser’;
import { NgModule } from '@angular/core’;
import { HttpClientInMemoryWebApiModule } from "angular-in-memory-web-api”;
import { HttpClientModule } from "@angular/common/http”;
import { AppComponent } from './app.component’;
import { DataService } from "./data.service”;
import { BooksModule } from './books/books.module’;
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
HttpClientInMemoryWebApiModule.forRoot(DataService),
BooksModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
在導(dǎo)入 HttpClientModule
模塊時(shí)轻纪,要讓 HttpClientModule
模塊位于 HttpClientInMemoryWebApiModule
模塊之前,使后者可以覆蓋前者的默認(rèn)行為龟糕。
- 在
HeroService
服務(wù)中注入HttpClient
.
import { Injectable } from '@angular/core’;
import { HttpClient } from "@angular/common/http”;
import { Book } from './book.model’;
@Injectable({
providedIn: ‘root’
})
export class BookService {
constructor(private http: HttpClient) { }
getBooks(): Book[] {
return [
{id: 1, name: '《三體》', price: 50.00},
{id: 2, name: '《黑暗森林》', price: 40.00},
{id: 3, name: '《死神永生》', price: 60.00},
{id: 4, name: '《超新星紀(jì)元》', price: 35.00}
];
}
}
- 修改
getBooks
方法桐磁,使其通過(guò)HttpClient
獲取圖書列表數(shù)據(jù)。
import { Injectable } from '@angular/core’;
import { HttpClient } from "@angular/common/http”;
import { Book } from './book.model’;
import { Observable } from ‘rxjs’;
@Injectable({
providedIn: ‘root’
})
export class BookService {
constructor(private http: HttpClient) { }
getBooks(): Observable<Book[]> {
return this.http.get<Book[]>('api/books’);
}
}
4.在 BookListComponent
類中讲岁,修改獲取圖書數(shù)據(jù)的邏輯我擂。
import { Component, OnInit } from '@angular/core’;
import { Book } from '../book.model’;
import { BookService } from '../book.service’;
@Component({
selector: 'app-book-list’,
templateUrl: './book-list.component.html’,
styleUrls: ['./book-list.component.css’]
})
export class BookListComponent implements OnInit {
books: Book[];
constructor(private bookService: BookService) {
}
ngOnInit(): void {
this.getBooks();
}
private getBooks() {
this.bookService.getBooks().subscribe(books => this.books = books);
}
}
驗(yàn)證訪問(wèn)效果
在頁(yè)面上圖書列表時(shí),會(huì)有一些延時(shí)缓艳,這是內(nèi)存 Web API 模擬了真實(shí)的請(qǐng)求/響應(yīng)的處理時(shí)間校摩。我們可以在 HttpClientInMemoryWebApiModule
模塊的 forRoot
方法配置 delay
屬性,改變延時(shí)時(shí)長(zhǎng)阶淘。