Angular 是一个流行的前端框架,它可以帮助我们构建复杂的单页应用程序。在这篇文章中,我们将学习如何使用 Angular 构建一个基于单页应用程序的 Ecommerce 网站。我们将使用 Angular 的各种特性,如组件、服务、路由和管道,来实现这个网站。
环境设置
在开始之前,确保你已经安装了 Node.js 和 Angular CLI。如果你还没有安装,可以访问官方网站进行下载和安装。
创建项目
使用 Angular CLI 创建一个新项目:
ng new ecommerce-app
这个命令将创建一个新的 Angular 项目,并安装所需的依赖项。
添加页面
我们将创建三个页面:首页、产品列表页和产品详情页。我们将使用 Angular 的路由来实现这些页面之间的导航。
首页
在 src/app 目录下创建一个新的组件:home。
ng generate component home
在 home.component.html 文件中添加以下内容:
<h1>Welcome to Ecommerce Web Application</h1>
产品列表页
在 src/app 目录下创建一个新的组件:product-list。
ng generate component product-list
在 product-list.component.html 文件中添加以下内容:
<h1>Product List</h1>
产品详情页
在 src/app 目录下创建一个新的组件:product-detail。
ng generate component product-detail
在 product-detail.component.html 文件中添加以下内容:
<h1>Product Detail</h1>
添加路由
在 app-routing.module.ts 文件中添加以下路由:
// www.javascriptcn.com code example
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { ProductListComponent } from './product-list/product-list.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'products', component: ProductListComponent },
{ path: 'products/:id', component: ProductDetailComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }这个路由定义了三个路径:/、/products 和 /products/:id。当用户访问这些路径时,将分别显示 HomeComponent、ProductListComponent 和 ProductDetailComponent。
添加服务
我们需要一个服务来获取产品列表和产品详情。在 src/app 目录下创建一个新的服务:product.service.ts。
ng generate service product
在 product.service.ts 文件中添加以下内容:
// www.javascriptcn.com code example
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ProductService {
private productsUrl = 'api/products';
httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
constructor(private http: HttpClient) { }
getProducts(): Observable<Product[]> {
return this.http.get<Product[]>(this.productsUrl)
.pipe(
tap(_ => console.log('fetched products')),
catchError(this.handleError<Product[]>('getProducts', []))
);
}
getProduct(id: number): Observable<Product> {
const url = `${this.productsUrl}/${id}`;
return this.http.get<Product>(url).pipe(
tap(_ => console.log(`fetched product id=${id}`)),
catchError(this.handleError<Product>(`getProduct id=${id}`))
);
}
private handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
console.error(error);
console.log(`${operation} failed: ${error.message}`);
return of(result as T);
};
}
}这个服务使用 Angular 的 HttpClient 来获取产品列表和产品详情。getProducts 方法将返回一个 Observable,它将 Product 数组作为值。getProduct 方法将返回一个 Observable,它将单个 Product 作为值。
添加管道
我们将使用 Angular 的管道来格式化价格。在 src/app 目录下创建一个新的管道:price.pipe.ts。
ng generate pipe price
在 price.pipe.ts 文件中添加以下内容:
// www.javascriptcn.com code example
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'price'
})
export class PricePipe implements PipeTransform {
transform(value: number): string {
return `$${value.toFixed(2)}`;
}
}这个管道将接受一个数字,将其格式化为美元金额,并返回一个字符串。
更新组件
现在我们需要更新组件来使用服务和管道。在 home.component.ts 文件中添加以下内容:
// www.javascriptcn.com code example
import { Component, OnInit } from '@angular/core';
import { ProductService } from '../product.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
constructor(private productService: ProductService) { }
ngOnInit(): void {
}
}在 product-list.component.ts 文件中添加以下内容:
// www.javascriptcn.com code example
import { Component, OnInit } from '@angular/core';
import { ProductService } from '../product.service';
import { Product } from '../product';
@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html',
styleUrls: ['./product-list.component.css']
})
export class ProductListComponent implements OnInit {
products: Product[];
constructor(private productService: ProductService) { }
ngOnInit(): void {
this.getProducts();
}
getProducts(): void {
this.productService.getProducts()
.subscribe(products => this.products = products);
}
}在 product-list.component.html 文件中添加以下内容:
<h1>Product List</h1>
<ul>
<li *ngFor="let product of products">
<a [routerLink]="['/products', product.id]">{{ product.name }}</a>
<p>{{ product.price | price }}</p>
</li>
</ul>在 product-detail.component.ts 文件中添加以下内容:
// www.javascriptcn.com code example
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { ProductService } from '../product.service';
import { Product } from '../product';
@Component({
selector: 'app-product-detail',
templateUrl: './product-detail.component.html',
styleUrls: ['./product-detail.component.css']
})
export class ProductDetailComponent implements OnInit {
product: Product;
constructor(
private route: ActivatedRoute,
private productService: ProductService,
private location: Location
) { }
ngOnInit(): void {
this.getProduct();
}
getProduct(): void {
const id = +this.route.snapshot.paramMap.get('id');
this.productService.getProduct(id)
.subscribe(product => this.product = product);
}
goBack(): void {
this.location.back();
}
}在 product-detail.component.html 文件中添加以下内容:
<h1>Product Detail</h1>
<div *ngIf="product">
<h2>{{ product.name }}</h2>
<p>{{ product.price | price }}</p>
<button (click)="goBack()">Back</button>
</div>添加模拟数据
我们需要一些模拟数据来测试我们的应用程序。在 src/app 目录下创建一个新的文件:mock-products.ts。
// www.javascriptcn.com code example
import { Product } from './product';
export const PRODUCTS: Product[] = [
{ id: 1, name: 'Product A', price: 10.99 },
{ id: 2, name: 'Product B', price: 19.99 },
{ id: 3, name: 'Product C', price: 5.99 },
{ id: 4, name: 'Product D', price: 15.99 },
{ id: 5, name: 'Product E', price: 9.99 },
{ id: 6, name: 'Product F', price: 12.99 }
];在 app.module.ts 文件中添加以下内容:
// www.javascriptcn.com code example
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { ProductListComponent } from './product-list/product-list.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
import { PricePipe } from './price.pipe';
import { ProductService } from './product.service';
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { ProductData } from './product-data';
@NgModule({
declarations: [
AppComponent,
HomeComponent,
ProductListComponent,
ProductDetailComponent,
PricePipe
],
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule,
InMemoryWebApiModule.forRoot(ProductData)
],
providers: [ProductService],
bootstrap: [AppComponent]
})
export class AppModule { }这个模块将使用 InMemoryWebApiModule 来模拟一个 Web API。我们还需要创建一个新的类:product-data.ts。
// www.javascriptcn.com code example
import { InMemoryDbService } from 'angular-in-memory-web-api';
import { PRODUCTS } from './mock-products';
export class ProductData implements InMemoryDbService {
createDb() {
const products = PRODUCTS;
return { products };
}
}这个类将创建一个 products 数据库,其中包含我们的模拟产品数据。
运行应用程序
现在我们已经完成了我们的应用程序。使用以下命令启动应用程序:
ng serve --open
这个命令将启动应用程序,并在浏览器中打开它。现在我们可以在浏览器中访问 http://localhost:4200,并在我们的应用程序中浏览产品。
结论
在本文中,我们学习了如何使用 Angular 构建一个基于单页应用程序的 Ecommerce 网站。我们使用了 Angular 的各种特性,如组件、服务、路由和管道,来实现这个网站。我们还学习了如何使用 InMemoryWebApiModule 来模拟一个 Web API,并使用模拟数据测试我们的应用程序。我希望这篇文章能够帮助你更好地理解 Angular,并为你构建自己的应用程序提供指导。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/676017e903c3aa6a56fc7933