angular 模块构建

Angular is one of the three most popular frameworks for front-end development, alongside React and Vue.js. The latest version is Angular 8 which was released on May 28, 2019.

Angular是与React和Vue.js并排的三种最受欢迎​​的前端开发框架之一。 最新版本是Angular 8,已于2019年5月28日发布。

There are many new features and enhancements to both the command-line interface and the framework itself which result in a performance-boost and smaller production bundles. One interesting feature is the ng deploy command which allows developers to quickly build and deploy their Angular apps to popular hosting providers such as Firebase or GitHub.

命令行界面和框架本身都有许多新功能和增强功能,从而提高了性能,并减少了生产量。 ng deploy命令是一项有趣的功能,它使开发人员可以快速将Angular应用程序构建和部署到流行的托管提供商(例如Firebase或GitHub)。

In this tutorial, we’ll take you step by step on a journey to build an example Angular application from scratch that uses many Angular APIs such as HttpClient, and Material Design.

在本教程中,我们将逐步引导您从头开始构建一个使用许多Angular API(例如HttpClient和Material Design)的示例Angular应用程序。

Here are a few things we'll learn:

这是我们将要学习的一些知识:

  • How to mock a REST API server that uses fake data from a JSON file 如何模拟使用JSON文件中的伪数据的REST API服务器
  • How to consume the REST API from our Angular 8 application using  Httplient

    如何使用Httplient从Angular 8应用程序中使用REST API

  • How to handle HTTP errors using the RxJS  throwError()  and  catchError()  operators

    如何使用RxJS throwError()catchError()运算符处理HTTP错误

  • How to retry failed HTTP requests in poor network conditions and cancel pending requests using the RxJS  retry()  and  takeUntil() operators

    如何在恶劣的网络条件下重试失败的HTTP请求以及如何使用RxJS retry()takeUntil()运算符取消待处理的请求

  • How to create and make use of Angular components and services 如何创建和利用Angular组件和服务
  • How to set up routing and Angular Material in our project and create a professional-looking UI with Material Design components如何在我们的项目中设置Craft.io路线和Angular Material,以及如何使用Material Design组件创建具有专业外观的UI
  • And finally, we’ll learn how to deploy the application to Firebase using the  ng deploy  command available in Angular 8.3+.

    最后,我们将学习如何使用Angular 8.3+中提供的ng deploy命令将应用程序部署到Firebase。

You’ll also learn by example:

您还将通过示例学习:

  • How to quickly mock a REST API with real-world features, such as pagination, that you can consume from your app before you can switch to a real backend when it’s ready.如何快速模拟具有现实世界功能(例如分页)的REST API,您可以从应用程序中使用这些功能,然后在准备就绪时切换到真实的后端。
  • How to set up Angular CLI如何设置Angular CLI
  • How to initialize your Angular 8 project如何初始化Angular 8项目
  • How to set up Angular Material如何设置角材料
  • How to add Angular components and routing如何添加Angular组件和路由
  • How to generate and use Angular services如何生成和使用Angular服务
  • How to consume REST APIs with Angular HttpClient如何使用Angular HttpClient使用REST API
  • How to build and deploy your Angular application to Firebase.如何将Angular应用程序构建和部署到Firebase。

This tutorial is divided into the following steps:

本教程分为以下步骤:

  • Step 1 — Installing Angular CLI 8第1步-安装Angular CLI 8
  • Step 2 — Creating your Angular 8 Project第2步-创建Angular 8项目
  • Step 3 — Adding Angular HttpClient第3步—添加Angular HttpClient
  • Step 4 — Creating Components第4步-创建组件
  • Step 5 — Adding Routing步骤5 —添加路由
  • Step 6 — Building the UI with Angular Material Components第6步-使用Angular材质组件构建UI
  • Step 7 — Mocking a REST API第7步-模拟REST API
  • Step 8 — Consuming the REST API with Angular HttpClient第8步—使用Angular HttpClient使用REST API
  • Step 9 — Handling HTTP Errors步骤9 —处理HTTP错误
  • Step 10 — Adding Pagination第10步-添加分页
  • Step 11 — Building and Deploying your Angular Application to Firebase第11步–将您的Angular应用程序构建和部署到Firebase

Now, let’s get started with the prerequisites!

现在,让我们开始先决条件!

Note: you can download our Angular 8 Book: Build your first web apps with Angular 8 for free.

注意 :您可以免费下载我们的Angular 8图书:使用Angular 8构建您的第一个Web应用程序

先决条件 (Prerequisites)

If you want to follow this tutorial, you’ll need to have:

如果要遵循本教程,则需要具备以下条件:

  • Prior knowledge of TypeScript.具有TypeScript的先验知识。
  • A development machine with  Node 8.9+ and  NPM 5.5.1+  installed. Node is required by the Angular CLI. You can head to the official website and grab the binaries for your system. You can also use  NVM  — Node Version Manager — a POSIX-compliant bash script to install and manage multiple Node.js versions in your machine.

    安装了Node 8.9+NPM 5.5.1+的开发机器。 Angular CLI需要节点。 您可以访问官方网站并获取系统的二进制文件。 您还可以使用NVM-节点版本管理器-POSIX兼容的bash脚本在计算机中安装和管理多个Node.js版本。

If you are ready, let’s learn by example how to build an Angular 8 application that consumes a REST API using HttpClient. We'll implement real-world features like error handling and retrying failed HTTP requests.

如果您准备好了,让我们通过示例学习如何使用HttpClient构建使用REST API的Angular 8应用程序。 我们将实现实际功能,例如错误处理和重试失败的HTTP请求。

第1步-安装Angular CLI 8 (Step 1 — Installing Angular CLI 8)

Let’s start with the first step, where we’ll install the latest version of Angular CLI.

让我们从第一步开始,我们将安装最新版本的Angular CLI。

Angular CLI  is the official tool for initializing and working with Angular projects. Head to a new terminal and execute the following command:

Angular CLI是用于初始化和使用Angular项目的官方工具。 转到新终端并执行以下命令:

$ npm install -g @angular/cli

When writing this tutorial,  angular/cli v8.3.2  is installed on our system.

在编写本教程时,我们的系统上已安装angular / cli v8.3.2

That’s it, you are ready for the second step!

就是这样,您已经准备好进行第二步!

第2步-创建Angular 8项目 (Step 2 — Creating your Angular 8 Project)

In this step, we’ll use Angular CLI to initialize our Angular project.

在此步骤中,我们将使用Angular CLI初始化Angular项目。

Go to your terminal and execute these commands:

转到终端并执行以下命令:

$ cd ~
$ ng new angular-example

The CLI will prompt you and ask whether you would like to add Angular routing. Say Yes. It'll then ask which stylesheet format you would like to use. Choose CSS.

CLI会提示您,并询问您是否要添加Angular路由。 说是。 然后它将询问您要使用哪种样式表格式。 选择CSS

Angular CLI will generate the required files and folders, install the packages from npm, and even automatically set up routing in our project.

Angular CLI将生成所需的文件和文件夹,从npm安装软件包,甚至在我们的项目中自动设置路由。

Now, go to your project’s root folder and run the local development server using these commands:

现在,转到项目的根文件夹,并使用以下命令运行本地开发服务器:

$ cd angular-example
$ ng serve

Your Angular web application will be available from the  [http://localhost:4200/](http://localhost:4200/)  address.

您可以从[http://localhost:4200/](http://localhost:4200/)地址访问Angular Web应用程序。

Open a web browser and go to the  http://localhost:4200/ address. You should see this beautiful page (Starting with Angular 8.3+):

打开Web浏览器,然后转到http://localhost:4200/地址。 您应该会看到这个漂亮的页面(从Angular 8.3+开始):

You need to leave the development server running and open a new terminal for the next steps.

您需要使开发服务器保持运行状态,并打开新终端以进行下一步。

You are now ready for the third step!

现在您已准备好进行第三步!

第3步—添加Angular HttpClient (Step 3 — Adding Angular HttpClient)

In this step, we’ll add  HttpClient  to our example project.

在这一步中,我们将HttpClient添加到示例项目中。

Open the  src/app/app.module.ts  file and make the following changes:

打开src/app/app.module.ts文件并进行以下更改:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';@NgModule({declarations: [AppComponent,],imports: [BrowserModule,AppRoutingModule,HttpClientModule],providers: [],bootstrap: [AppComponent]
})
export class AppModule { }

We simply imported HttpClientModule and included it in the imports array.

我们只导入了HttpClientModule并将其包含在imports数组中。

That’s all - now we can use the  HttpClient  service in our Angular project to consume our REST API.

就是这样-现在我们可以在Angular项目中使用HttpClient服务来使用我们的REST API。

You are ready for the fifth step!

您已准备好进行第五步!

第4步-创建UI组件 (Step 4 — Creating UI Components)

Angular apps are made up of components. In this step, we’ll learn how to create a couple of Angular components that compose our UI.

Angular应用由组件组成。 在这一步中,我们将学习如何创建几个构成UI的Angular组件。

Open a new terminal and run the following command:

打开一个新的终端并运行以下命令:

$ cd ~/angular-example
$ ng g component home

You’ll get the following output in your terminal:

您将在终端中获得以下输出:

CREATE src/app/home/home.component.html (19 bytes)
CREATE src/app/home/home.component.spec.ts (614 bytes)
CREATE src/app/home/home.component.ts (261 bytes)
CREATE src/app/home/home.component.css (0 bytes)
UPDATE src/app/app.module.ts (467 bytes)

We have four files, all required by our component.

我们有四个文件,它们都是组件所必需的。

Next, generate the about component:

接下来,生成about组件:

$ ng g component about

Next, open the  src/app/about/about.component.html  file and add the following code:

接下来,打开src/app/about/about.component.html文件并添加以下代码:

<p style="padding: 15px;"> This is the about page that describes your app</p>

You are ready for the sixth step!

您已准备好进行第六步!

步骤5 —添加路由 (Step 5 — Adding Routing)

In this step, we’ll learn how to add routing to our example.

在这一步中,我们将学习如何在示例中添加路由。

Go to the  src/app/app-routing.module.ts  file and add the following routes:

转到src/app/app-routing.module.ts文件并添加以下路由:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';const routes: Routes = [{ path: '', redirectTo: 'home', pathMatch: 'full'},{ path: 'home', component: HomeComponent },{ path: 'about', component: AboutComponent },
];@NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule]
})
export class AppRoutingModule { }

We imported the Angular components and we declared three routes.

我们导入了Angular组件,并声明了三条路线。

The first route is for redirecting the empty path to the home component, so we’ll be automatically redirected to the home page when we first visit the app.

第一条路线是将空路径重定向到主页组件,因此,当我们首次访问该应用程序时,我们将自动重定向到主页。

That’s it. Now that you have added routing, you are ready for the next step!

而已。 现在,您已经添加了路由,可以开始下一步了!

第6步—添加角材料 (Step 6 — Adding Angular Material)

In this tutorial step, we’ll learn to set up Angular Material in our project and build our application UI using Material components.

在本教程步骤中,我们将学习在项目中设置Angular Material并使用Material组件构建应用程序UI。

Go to your terminal and run this command from the root of your project:

转到终端并从项目的根目录运行以下命令:

$ ng add @angular/material

You’ll be prompted to choose the theme, so let’s pick Indigo/Pink.

系统将提示您选择主题,因此让我们选择Indigo / Pink

For the other questions - whether you want to set up HammerJS for gesture recognition and if you want to set up browser animations for Angular Material - press Enter to use the default answers.

对于其他问题-是否要设置HammerJS进行手势识别以及是否要为Angular Material设置浏览器动画 -请按Enter键以使用默认答案。

Open the  src/app/app.module.ts  file and add the following imports:

打开src/app/app.module.ts文件并添加以下导入:

import { MatToolbarModule,MatIconModule,MatCardModule,MatButtonModule,MatProgressSpinnerModule } from '@angular/material';

We imported the modules for these Material Design components:

我们导入了这些材料设计组件的模块:

  • MatToolbar that provides a container for headers, titles, or actions.

    MatToolbar ,提供标题,标题或操作的容器。

  • MatCard that provides a content container for text, photos, and actions in the context of a single subject.

    MatCard ,它为单个主题的上下文中的文本,照片和动作提供内容容器。

  • MatButton that provides a native  <button>  or  <a>  element enhanced with Material Design styling and ink ripples.

    MatButton提供了本机的<button><a>元素,并通过Material Design样式和墨水波纹进行了增强。

  • MatProgressSpinner that provides a circular indicator of progress and activity.

    MatProgressSpinner ,提供进度和活动的循环指示器。

Next, add these modules to the  imports  array:

接下来,将这些模块添加到imports数组:

@NgModule({declarations: [AppComponent,HomeComponent,AboutComponent],imports: [BrowserModule,AppRoutingModule,HttpClientModule,BrowserAnimationsModule,MatToolbarModule,MatIconModule,MatButtonModule,MatCardModule,MatProgressSpinnerModule],providers: [],bootstrap: [AppComponent]
})
export class AppModule { }

Next, open the  src/app/app.component.html  file and update it as follows:

接下来,打开src/app/app.component.html文件并按如下所示进行更新:

<mat-toolbar color="primary">
<h1>
My Angular Store
</h1>
<button mat-button routerLink="/">Home</button>
<button mat-button routerLink="/about">About</button></mat-toolbar><router-outlet></router-outlet>

We added a top navigation bar with two buttons that take us to the home and about pages, respectively.

我们添加了带有两个按钮的顶部导航栏,分别将我们带到主页和关于页面。

第7步-模拟REST API (Step 7 — Mocking a REST API)

Go to a new command-line interface and start by installing  json-server  from npm in your project:

转到新的命令行界面,然后从项目中的npm安装json-server开始:

$ cd ~/angular-example
$ npm install --save json-server

Next, create a  server  folder in the root folder of your Angular project:

接下来,在Angular项目的根文件夹中创建一个server文件夹:

$ mkdir server
$ cd server

In the  server  folder, create a  database.json  file and add the following JSON object:

server文件夹中,创建一个database.json文件并添加以下JSON对象:

{"products": []
}

This JSON file will act as a database for your REST API server. You can simply add some data to be served by your REST API or use Faker.js for automatically generating massive amounts of realistic fake data.

此JSON文件将充当您的REST API服务器的数据库。 您可以简单地添加一些要由REST API提供服务的数据,也可以使用Faker.js自动生成大量逼真的假数据。

Go back to your command-line, navigate back from the  server  folder, and install Faker.js  from npm using the following command:

返回命令行,从server文件夹导航回去,并使用以下命令从npm安装Faker.js

$ cd ..
$ npm install faker --save

At the time of creating this example, faker v4.1.0 will be installed.

在创建此示例时,将安装faker v4.1.0

Now, create a  generate.js  file and add the following code:

现在,创建一个generate.js文件并添加以下代码:

var faker = require('faker');var database = { products: []};for (var i = 1; i<= 300; i++) {database.products.push({id: i,name: faker.commerce.productName(),description: faker.lorem.sentences(),price: faker.commerce.price(),imageUrl: "https://source.unsplash.com/1600x900/?product",quantity: faker.random.number()});
}console.log(JSON.stringify(database));

We first imported faker, and next we defined an object with one empty array for products. Next, we entered a for loop to create 300 fake entries using faker methods like  faker.commerce.productName()  for generating product names. Check all the available methods. Finally we converted the database object to a string and logged it to standard output.

我们首先导入了faker,然后我们定义了一个带有一个空数组的产品对象。 接下来,我们进入一个for循环,使用诸如faker.commerce.productName()类的伪造方法来创建300个伪造条目,以生成产品名称。 检查所有可用方法 。 最后,我们将数据库对象转换为字符串,并将其记录到标准输出中。

Next, add the  generate  and  server  scripts to the  package.json  file:

接下来,将generateserver脚本添加到package.json文件:

"scripts": {"ng": "ng","start": "ng serve","build": "ng build","test": "ng test","lint": "ng lint","e2e": "ng e2e","generate": "node ./server/generate.js > ./server/database.json","server": "json-server --watch ./server/database.json"},

Next, head back to your command-line interface and run the generate script using the following command:

接下来,返回您的命令行界面,并使用以下命令运行generate脚本:

$ npm run generate

Finally, run the REST API server by executing the following command:

最后,通过执行以下命令来运行REST API服务器:

$ npm run server

You can now send HTTP requests to the server just like any typical REST API server. Your server will be available from the  http://localhost:3000/  address.

现在,您可以像任何典型的REST API服务器一样将HTTP请求发送到服务器。 您的服务器将可从http://localhost:3000/地址获得。

These are the API endpoints we'll be able to use via our JSON REST API server:

这些是我们可以通过JSON REST API服务器使用的API端点:

  • GET /products  for getting the products

    GET /products获取产品

  • GET /products/<id>  for getting a single product by id

    GET /products/<id>用于通过id获取单个产品

  • POST /products  for creating a new product

    POST /products用于创建新产品

  • PUT /products/<id>  for updating a product by id

    PUT /products/<id>用于通过id更新产品

  • PATCH /products/<id>  for partially updating a product by id

    PATCH /products/<id>用于按ID部分更新产品

  • DELETE /products/<id>  for deleting a product by id

    DELETE /products/<id>用于通过ID删除产品

You can use  _page  and  _limit  parameters to get paginated data. In the  Link header you'll get  first,  prev,  next  and  last  links.

您可以使用_page_limit参数获取分页数据。 在Link标头中,您将获得firstprevnextlast链接。

Leave the JSON REST API server running and open a new command-line interface for typing the commands of the next steps.

使JSON REST API服务器保持运行状态,并打开一个新的命令行界面,以键入后续步骤的命令。

步骤8 —创建用于使用Angular HttpClient消耗REST API的服务 (Step 8 — Creating a Service for Consuming the REST API with Angular HttpClient)

In this step, we’ll learn how to consume our REST API from Angular using HttpClient.

在这一步中,我们将学习如何使用HttpClient从Angular使用REST API。

We’ll need to create an Angular service for encapsulating the code that allows us to consume data from our REST API server.

我们需要创建一个Angular服务来封装代码,使我们能够使用来自REST API服务器的数据。

Go to your terminal and run the following command:

转到终端并运行以下命令:

$ ng g service api

Next, go to the  src/app/api.service.ts  file, import and inject  HttpClient:

接下来,转到src/app/api.service.ts文件,导入并注入HttpClient

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';@Injectable({providedIn: 'root'
})
export class ApiService {private SERVER_URL = "http://localhost:3000";constructor(private httpClient: HttpClient) { }
}

We imported and injected the  HttpClient  service and defined the  SERVER_URL variable that contains the address of our REST API server.

我们导入并注入了HttpClient服务,并定义了包含REST API服务器地址的SERVER_URL变量。

Next, define a  get()  method that sends a GET request to the REST API endpoint:

接下来,定义一个get()方法,该方法将GET请求发送到REST API端点:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';@Injectable({  providedIn: 'root'
})
export class ApiService {private SERVER_URL = "http://localhost:3000";constructor(private httpClient: HttpClient) { }public get(){  return this.httpClient.get(this.SERVER_URL);  }
}

The method simply invokes the  get()  method of  HttpClient  to send GET requests to the REST API server.

该方法仅调用HttpClientget()方法将GET请求发送到REST API服务器。

Next, we now need to use this service in our home component. Open the src/app/home/home.component.ts  file, and import and inject the data service as follows:

接下来,我们现在需要在home组件中使用此服务。 打开src/app/home/home.component.ts文件,并按如下所示导入和注入数据服务:

import { Component, OnInit } from '@angular/core';
import { ApiService } from '../api.service';@Component({  selector: 'app-home',  templateUrl: './home.component.html',  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {products = [];constructor(private apiService: ApiService) { }ngOnInit() {this.apiService.get().subscribe((data: any[])=>{  console.log(data);  this.products = data;  })  }
}

We imported and injected  ApiService.  Next, we defined a  products  variable and called the  get()  method of the service for fetching data from the JSON REST API server.

我们导入并注入了ApiService. 接下来,我们定义了一个products变量,并调用了服务的get()方法,用于从JSON REST API服务器中获取数据。

Next, open the  src/app/home/home.component.html  file and update it as follows:

接下来,打开src/app/home/home.component.html文件并按如下所示进行更新:

<div style="padding: 13px;"><mat-spinner *ngIf="products.length === 0"></mat-spinner><mat-card *ngFor="let product of products" style="margin-top:10px;"><mat-card-header><mat-card-title>{{product.name}}</mat-card-title><mat-card-subtitle>{{product.price}} $/ {{product.quantity}}</mat-card-subtitle></mat-card-header><mat-card-content><p>{{product.description}}</p><img style="height:100%; width: 100%;" src="{{ product.imageUrl }}" /></mat-card-content><mat-card-actions><button mat-button> Buy product</button></mat-card-actions></mat-card>
</div>

We used the  <mat-spinner>  component for showing a loading spinner when the length of the  products  array equals zero, that is before any data is received from the REST API server.

products数组的长度等于零(即从REST API服务器接收到任何数据之前)时,我们使用<mat-spinner>组件显示了一个加载微调器。

Next, we iterated over the  products  array and used a Material card to display the name,  price,  quantity,  description  and  image  of each product.

接下来,我们遍历products阵列,并使用Material卡显示每个产品的namepricequantitydescriptionimage

This is a screenshot of the home page after JSON data is fetched:

这是获取JSON数据后的主页的屏幕截图:

Next, we’ll see how to add error handling to our service.

接下来,我们将看到如何向我们的服务添加错误处理。

步骤9 —添加错误处理 (Step 9 — Adding Error Handling)

In this step, we’ll learn to add error handling in our example.

在这一步中,我们将学习在示例中添加错误处理。

Go to the  src/app/api.service.ts  file and update it as follows:

转到src/app/api.service.ts文件并按如下所示进行更新:

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from "@angular/common/http";import {  throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';@Injectable({providedIn: 'root'
})
export class ApiService {private SERVER_URL = "http://localhost:3000/products";constructor(private httpClient: HttpClient) { }handleError(error: HttpErrorResponse) {let errorMessage = 'Unknown error!';if (error.error instanceof ErrorEvent) {// Client-side errorserrorMessage = `Error: ${error.error.message}`;} else {// Server-side errorserrorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;}window.alert(errorMessage);return throwError(errorMessage);}public sendGetRequest(){return this.httpClient.get(this.SERVER_URL).pipe(catchError(this.handleError));}
}

This is a screenshot of an example error on the browser console:

这是浏览器控制台上的示例错误的屏幕截图:

In the next step, we’ll see how to add pagination to our application

在下一步中,我们将看到如何在应用程序中添加分页

第10步-添加分页 (Step 10 — Adding Pagination)

In this step, we’ll learn to add support for data pagination using the Link header of the HTTP response received from the REST API server.

在这一步中,我们将学习使用从REST API服务器接收的HTTP响应的Link标头添加对数据分页的支持。

By default, HttpClient provides only the response body. But in our app we need to parse the Link header for extracting pagination links. So we need to instructHttpClient  to give us the full HttpResponse using the  observe  option.

默认情况下,HttpClient仅提供响应主体。 但是在我们的应用程序中,我们需要解析Link标头以提取分页链接。 因此,我们需要指示HttpClient使用observe选项向我们提供完整的HttpResponse 。

The Link header in HTTP allows the server to point an interested client to another resource containing metadata about the requested resource. Wikipedia

HTTP中的Link标头允许服务器将感兴趣的客户端指向包含有关所请求资源的元数据的另一个资源。 维基百科

Open the src/app/data.service.ts file and import the RxJS  tap()  operator:

打开src/app/data.service.ts文件并导入RxJS tap()运算符:

import { retry, catchError, tap } from 'rxjs/operators';

Next, add these variables:

接下来,添加以下变量:

public first: string = "";
public prev: string = "";
public next: string = "";
public last: string = "";

Next, add the  parseLinkHeader()  method that will be used to parse the Link header and populates the previous variables:

接下来,添加parseLinkHeader()方法,该方法将用于解析Link标头并填充先前的变量:

parseLinkHeader(header) {if (header.length == 0) {return ;}let parts = header.split(',');var links = {};parts.forEach( p => {let section = p.split(';');var url = section[0].replace(/<(.*)>/, '$1').trim();var name = section[1].replace(/rel="(.*)"/, '$1').trim();links[name] = url;});this.first  = links["first"];this.last   = links["last"];this.prev   = links["prev"];this.next   = links["next"]; }

Next, update the  sendGetRequest()  as follows:

接下来,如下更新sendGetRequest()

public sendGetRequest(){// Add safe, URL encoded _page and _limit parameters return this.httpClient.get(this.SERVER_URL, {  params: new HttpParams({fromString: "_page=1&_limit=20"}), observe: "response"}).pipe(retry(3), catchError(this.handleError), tap(res => {console.log(res.headers.get('Link'));this.parseLinkHeader(res.headers.get('Link'));}));}

We added the  observe  option with the  response  value in the options parameter of the  get()  method so we can have the full HTTP response with headers. Next, we use the RxJS  tap()  operator for parsing the Link header before returning the final Observable.

我们在get()方法的options参数中添加了带有response值的observe选项,因此我们可以获得带有标头的完整HTTP响应。 接下来,我们使用RxJS tap()运算符在返回最终的Observable之前解析Link头。

Since the  sendGetRequest()  is now returning an Observable with a full HTTP response, we need to update the home component so open the  src/app/home/home.component.ts  file and import  HttpResponse  as follows:

由于sendGetRequest()现在将返回带有完整HTTP响应的Observable,因此我们需要更新home组件,因此打开src/app/home/home.component.ts文件并按如下所示导入HttpResponse

import { HttpResponse } from '@angular/common/http';

Next, update the  subscribe()  method as follows:

接下来,更新如下的subscribe()方法:

ngOnInit(){this.apiService.sendGetRequest().pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>)=>{  console.log(res);  this.products = res.body;
})
}

We can now access the data from the  body  object of the received HTTP response.

现在,我们可以从接收到的HTTP响应的body对象访问数据。

Next, go back to the src/app/data.service.ts file and add the following method:

接下来,返回src / app / data.service.ts文件并添加以下方法:

public sendGetRequestToUrl(url: string){  return this.httpClient.get(url, { observe: "response"}).pipe(retry(3),            catchError(this.handleError), tap(res => {  console.log(res.headers.get('Link'));  this.parseLinkHeader(res.headers.get('Link'));}));
}

This method is similar to  sendGetRequest()  except that it takes the URL to which we need to send an HTTP GET request.

此方法类似于sendGetRequest()不同之处在于它采用了我们需要向其发送HTTP GET请求的URL。

Go back to the  src/app/home/home.component.ts  file and add define the following methods:

返回src/app/home/home.component.ts文件并添加定义以下方法:

public firstPage() {this.products = [];this.apiService.sendGetRequestToUrl(this.apiService.first).pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>) => {console.log(res);this.products = res.body;})}public previousPage() {if (this.apiService.prev !== undefined && this.apiService.prev !== '') {this.products = [];this.apiService.sendGetRequestToUrl(this.apiService.prev).pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>) => {console.log(res);this.products = res.body;})}}public nextPage() {if (this.apiService.next !== undefined && this.apiService.next !== '') {this.products = [];this.apiService.sendGetRequestToUrl(this.apiService.next).pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>) => {console.log(res);this.products = res.body;})}}public lastPage() {this.products = [];this.apiService.sendGetRequestToUrl(this.apiService.last).pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>) => {console.log(res);this.products = res.body;})}

Finally, open the  src/app/home/home.component.html  file and update the template as follows:

最后,打开src/app/home/home.component.html文件并按如下所示更新模板:

<div style="padding: 13px;"><mat-spinner *ngIf="products.length === 0"></mat-spinner><mat-card *ngFor="let product of products" style="margin-top:10px;"><mat-card-header><mat-card-title>#{{product.id}} {{product.name}}</mat-card-title><mat-card-subtitle>{{product.price}} $/ {{product.quantity}}</mat-card-subtitle></mat-card-header><mat-card-content><p>{{product.description}}</p><img style="height:100%; width: 100%;" src="{{ product.imageUrl }}" /></mat-card-content><mat-card-actions><button mat-button> Buy product</button></mat-card-actions></mat-card></div>
<div><button (click) ="firstPage()" mat-button> First</button><button (click) ="previousPage()" mat-button> Previous</button><button (click) ="nextPage()" mat-button> Next</button><button (click) ="lastPage()" mat-button> Last</button>
</div>

This is a screenshot of our application:

这是我们的应用程序的屏幕截图:

第11步–将您的Angular应用程序构建和部署到Firebase (Step 11 — Building and Deploying your Angular Application to Firebase)

Head back to your command-line interface. Make sure you are inside the root folder of your Angular project and run the following command:

回到您的命令行界面。 确保您位于Angular项目的根文件夹中,然后运行以下命令:

$ ng add @angular/fire

This will add the Firebase deployment capability to your project.

这会将Firebase部署功能添加到您的项目中。

As the time of writing this tutorial, @angular/fire v5.2.1 will be installed.

在撰写本教程时,将安装@ angular / fire v5.2.1

The command will also update the  package.json  of our project by adding this section:

该命令还将通过添加以下部分来更新我们项目的package.json

"deploy": {"builder": "@angular/fire:deploy","options": {}}

The CLI will prompt you to Paste authorization code here: and will open your default web browser and ask you to give Firebase CLI permissions to administer your Firebase account.

CLI会提示您在此处粘贴授权代码:并将打开默认的Web浏览器,并要求您授予Firebase CLI权限来管理您的Firebase帐户。

After you sign in with the Google account associated with your Firebase account, you'll be given the authorization code.

使用与您的Firebase帐户关联的Google帐户登录后,将获得授权码。

Next, you'll be prompted to Please select a project: (Use arrow keys or type to search). You should have created a Firebase project before.

接下来,系统将提示您选择一个项目:(使用箭头键或键入搜索内容) 。 您之前应该已经创建了Firebase项目。

The CLI will create the  firebase.json  and  .firebaserc  files and update the angular.json  file accordingly.

该CLI将创建firebase.json.firebaserc文件和更新angular.json相应文件。

Next, deploy your application to Firebase using the following command:

接下来,使用以下命令将您的应用程序部署到Firebase:

$ ng deploy

The command will produce an optimized build of your application (equivalent to the ng deploy --prod  command). It will upload the production assets to Firebase hosting.

该命令将为您的应用程序生成优化的版本(相当于ng deploy --prod命令)。 它将生产资产上载到Firebase托管。

结论 (Conclusion)

Throughout this step by step tutorial, you learned to build an Angular application from scratch using the latest Angular 8.3+ version.

在本逐步教程中,您学习了使用最新的Angular 8.3+版本从头开始构建Angular应用程序的过程。

You learned to mock a REST API backend for your Angular application with nearly zero lines of code.

您学会了使用几乎零行代码为Angular应用程序模拟REST API后端。

You learned how to create a project using Angular CLI, add  HttpClient  and Angular Material for sending HTTP requests to your mocked REST API backend, and style the UI with Material Design components.

您学习了如何使用Angular CLI创建项目,如何添加HttpClient和Angular Material以便将HTTP请求发送到模拟的REST API后端,以及如何使用Material Design组件对UI进行样式设置。

Finally, you learned to deploy your Angular application to Firebase using the  ng deploy  command available starting from Angular 8.3+.

最后,您学习了使用从Angular 8.3+开始可用的ng deploy命令将Angular应用程序部署到Firebase。

Check out our other Angular tutorials.

看看我们其他的Angular教程 。

You can reach out to or follow the author via his:

您可以通过以下方式与作者联系或关注作者:

  • Personal website

    个人网站

  • Twitter

    推特

  • LinkedIn

    领英

  • Github

    Github

翻译自: https://www.freecodecamp.org/news/angular-8-tutorial-in-easy-steps/

angular 模块构建

angular 模块构建_如何通过11个简单的步骤从头开始构建Angular 8应用相关推荐

  1. 数据分析从头学_数据新闻学入门指南:让我们从头开始构建故事

    数据分析从头学 by Mina Demian 由Mina Demian 数据新闻学入门指南:让我们从头开始构建故事 (A Beginner's Guide to Data Journalism: Le ...

  2. react 组件添加样式_如何通过4个简单的步骤将CSS模块样式表添加到React组件

    react 组件添加样式 Let's say you'd like to add a CSS Modules Stylesheet to your project. You can find Crea ...

  3. django1.11 mysql配置_使用Django1.11创建简单的资产管理平台

    使用Django1.11创建简单的资产管理平台 发布时间:2020-06-05 00:06:17 来源:51CTO 阅读:883 作者:运维小学生 1:首先创建一个django项目[root@loca ...

  4. 梯度下降法优化目标函数_如何通过3个简单的步骤区分梯度下降目标函数

    梯度下降法优化目标函数 Nowadays we can learn about domains that were usually reserved for academic communities. ...

  5. vue nodejs 构建_如何使用nodejs后端打字稿版本开发和构建vue js应用

    vue nodejs 构建 There are so many ways we can build Vue.js apps and ship for production. One way is to ...

  6. ejb构建_如何使用单例EJB,Ehcache和MBean构建和清除参考数据缓存

    ejb构建 在本文中,我将介绍如何使用单例EJB和Ehcache在Java EE中构建简单的参考数据缓存. 高速缓存将在给定的时间段后重置自身,并且可以通过调用REST端点或MBean方法" ...

  7. web自动化构建_通过在真实设备上进行自动测试来构建更好的Web

    web自动化构建 This article was originally published on Medium. 本文最初发表在Medium上 . My work is entirely dedic ...

  8. java \t怎么从头开始_通过这些简单的步骤从头开始学习Java

    java \t怎么从头开始 Java是用于软件开发的最受欢迎的编程语言之一. 无论您的最终目标或技能水平如何,学习和掌握Java都将为您作为开发人员打开大门. 今天,我们将讨论一些原因,我们认为您应该 ...

  9. java开发简历编写_如何通过几个简单的步骤编写出色的初级开发人员简历

    java开发简历编写 So you've seen your dream junior developer role advertised, and are thinking about applyi ...

最新文章

  1. Nginx其他配置——日志管理、网页压缩、访问控制
  2. 微软摊开 AI 高分作业,在线求抄
  3. FTP服务(3)实现基于文件验证的vsftpd虚拟用户
  4. 多核学习在图像分类中的应用
  5. 一次性配置VS2015属性的方法,新工程无需重新配置
  6. PHP只下载不打开文件
  7. SAP Spartacus delivery mode continue button enable与否的逻辑
  8. Run service in specified proxyPort via jettyrun
  9. Android Studio项目结构介绍
  10. uos20专业版是linux哪个版本,WPS Office 2019 for Linux 专业版已与统一操作系统 UOS 完成适配...
  11. android mysql实现登录注册_android简单登陆和注册功能实现+SQLite数据库学习
  12. mysql:多表查询方式
  13. 模糊PID控制算法的C++实现
  14. 物联网周刊(第 5 期):智能家居入口之争
  15. error: ‘__ATOMIC_RELAXED’ undeclared (first use in this function)
  16. 测试小兵成长记:新兵营
  17. 循环神经网络--RNN GRU LSTM 对比分析
  18. jQuery浮出广告插件带关闭
  19. 苹果录屏功能没有声音_手机录屏没有声音如何处理?可以从这三个方面入手看看...
  20. O2OA:移动办公市场中的另一股清流

热门文章

  1. 日期时间选择器 DateTimePicker 1127
  2. 需求 实现轮播图效果 1022
  3. css 盒模型 0302
  4. request-爬取一张图片的练习-答案-私
  5. Ajax 和 PHP 实现验证码的实时验证
  6. springboot(四)——@EnableConfigurationProperties是如何起作用的你知道吗
  7. 想学大数据,应该从什么语言开始学?
  8. Struts2 ( 二 )
  9. 使用apache搭建tomcat集群
  10. .NET中使用Redis