根据Angular公式文档,理解Angular第3部分.

首先

我已经在Angular理解②中按照Angular官方文档的指导学习了路由设置的方法。接下来,我将继续按照官方文档的指导加深理解。
此外,由于本文正在进行本地环境的实施,因此使用了部分Angular CLI命令。有关本地环境的建立,请参考Angular官方教程中的本地环境设置部分。

Angular 教程

本文将根据数据管理的需要,采用修改和添加样本代码的方式进行进展。本文将执行以下操作。

    • カートに入れた商品リストを管理するカートサービスを追加

 

    • 商品の詳細ビューに Buy ボタンを追加

 

    • カート内の商品を表示するカートコンポーネントを追加

 

    HttpClient を使用して .json ファイルから配送料金を取得する shipping コンポーネントを追加

创建购物车服务

通过使用 Angular 的依赖注入(DI,Dependency Injection),我们指的是在应用程序的任意部分可以使用的类的实例。在本教程中,我们将创建一个购物车服务,让用户可以将商品添加到购物车中并保存购物车内商品的信息。

1. 服务的产生

首先,使用Angular CLI命令创建一个新的服务。将服务命名为cart。

$ ng g s cart # ng generate service cart でも可

执行后,将创建 src/app/cart.service.ts 和 src/app/cart.service.spec.ts 文件。(本次不使用 src/app/cart.service.spec.ts 文件。)

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class CartService {

  constructor() { }
}

因为对默认的@Injectable({providedIn: ‘root’})的意义不明,因此进行了调查。据说在@Injectable选项中的providedIn可以指定服务提供的范围,以提供依赖对象给模块。由于我不太能理解并且无法完全理解其含义,所以暂时将其放在这里。

2. 属性的定义

导入Product接口,并定义一个items属性,用于将商品数组存储到购物车中。

import { Injectable } from '@angular/core';
import { Product } from './products';

@Injectable({
  providedIn: 'root'
})
export class CartService {
  items: Product[] = [];

  constructor() { }
}

3. 方法的定义

定义一个 addToCart 方法来将商品添加到购物车,定义一个 getItems 方法来获取商品列表,定义一个 clearCart 方法来清空商品列表。

import { Injectable } from '@angular/core';
import { Product } from './products';

@Injectable({
  providedIn: 'root'
})
export class CartService {
  items: Product[] = [];

  constructor() { }

  addToCart(product: Product) {
    this.items.push(product);
  }

  getItems() {
    return this.items;
  }

  clearCart() {
    this.items = [];
    return this.items;
  }
}

使用购物车服务。

使用上述创建的购物车服务,将商品添加到购物车中。

1. 引入购物车服务

在”product-details.component.ts”中导入购物车服务。

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { Product, products } from '../products';
import { CartService } from '../cart.service';

...

购物车服务的提供

在product-details.component.ts中,添加并注入购物车服务到构造函数中,并定义使用注入的服务的addToCart方法。

...
export class ProductDetailsComponent implements OnInit {
  product: Product | undefined;

  constructor(
    private route: ActivatedRoute,
    private cartService: CartService
  ) {}

  ngOnInit() {
    // First get the product id from the current route.
    const routeParams = this.route.snapshot.paramMap;
    const productIdFromRoute = Number(routeParams.get('productId'));

    // Find the product that correspond with the id provided in route.
    this.product = products.find(product => product.id === productIdFromRoute);
  }

  addToCart(product: Product) {
    this.cartService.addToCart(product);
    window.alert('Your product has been added to the cart!');
  }
}

3. 事件绑定

将点击(click)事件绑定到上述定义的方法中的“购买”按钮。

<h2>Product Details</h2>

<div *ngIf="product">
  <h3>{{ product.name }}</h3>
  <h4>{{ product.price | currency }}</h4>
  <p>{{ product.description }}</p>

  <button (click)="addToCart(product)">Buy</button>
</div>

在商品详细页面上,显示了购买按钮,点击后可以确认显示一条消息。

创建购物车视图

添加一个查看已加入购物车商品的视图。

1. 组件的创建

首先,使用 Angular CLI 命令创建一个新的组件。将服务命名为 cart.

$ ng g c cart # ng generate component cart でも可

执行后,将创建src/app/cart目录。

2. 添加路由

为了处理创建的购物车组件,需要在app.module.ts中添加路径。(我认为还需要在declarations中添加,但是系统已经自动添加了。)

...
@NgModule({
  imports: [
    BrowserModule,
    ReactiveFormsModule,
    RouterModule.forRoot([
      { path: '', component: ProductListComponent },
      { path: 'products/:productId', component: ProductDetailsComponent },
      { path: 'cart', component: CartComponent }
    ])
  ],
  declarations: [
    AppComponent,
    TopBarComponent,
    ProductListComponent,
    ProductAlertsComponent,
    ProductDetailsComponent,
    CartComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

3. 添加 routerLink

请添加 routerLink 指令,将点击“Checkout”按钮后导航至上述添加到 /cart 的 URL。

<a [routerLink]="['/']">
  <h1>My Store</h1>
</a>

<a routerLink="/cart" class="button fancy-button">
  <i class="material-icons">shopping_cart</i>
  Checkout
</a>

当按下Checkout按钮时可以确认页面会发生转换。
在这里,使用My Store按钮的routerLink指令的写法([routerLink]=”[‘/’]”)似乎对包含变量(动态变化)的URL很有帮助,但在当前情况下只是看起来很冗长。我们可以将其简化为与Checkout按钮相同的routerLink=”/”。

4. 使用服务

刚才我在product-details.component.ts中使用购物车服务将商品添加到购物车中。现在我想在新创建的购物车组件中显示已添加到购物车的商品列表。因此,在cart.component.ts中我使用购物车服务来获取商品列表。

export class CartComponent {
  items = this.cartService.getItems();

  constructor(
    private cartService: CartService
  ) { }
}

根据以上规定,购物车中的商品列表将被存储在items属性中。最后,在cart.component.html文件中编写代码以显示商品的名称和价格。

<h3>Cart</h3>

<div class="cart-item" *ngFor="let item of items">
  <span>{{ item.name }}</span>
  <span>{{ item.price | currency }}</span>
</div>

可以看到各种不同的实施方式。

最后

在数据管理方面,虽然还有使用 HttpClient 等的方法,但我决定现在先暂时停止。因为我已经理解了 Angular 的基本组件、模板、服务和依赖注入,所以在之后实际开发应用程序时,如果遇到不明白的部分,我会逐步调查并继续进行下去。

广告
将在 10 秒后关闭
bannerAds