Angular 入门到精通 #05 - Managing data

252 阅读2分钟

我们在本节会继续完善产品详情页面,

  • 增加Buy按钮
  • 创建shopping cart组件
  • 使用HttpClient来获取shipping数据

创建 shopping cart service

定义cart service

  1. 运行如下的命令来创建cart service

    ng generate service cart
    
  2. 在cart service中,定义一个属性items,用来存储shopping cart里的产品。

    export class CartService {
      items: Product[] = [];
    }
    
  3. 定义三个方法,分别用来添加产品购物车,获取购物车里的数据和清空购物车。

    export class CartService {
      items: Product[] = [];
    
      constructor() { }
    
      addToCart (product: Product) {
        this.items.push(product);
      }
    
      getItems() {
        return this.items;
      }
    
      clearCart() {
        this.items = [];
        return this.items;
      }
    }
    

使用cart service

  1. 注入cart service 到product-details组件。

    export class ProductDetailsComponent {
      product: Product | undefined;
    
      constructor(
        private route: ActivatedRoute,
        private readonly productsService: ProductsService,
        private readonly cartService: CartService
      ){}
    }
    
  2. 定义addToCart()方法,用来把产品添加到购物车。

    export class ProductDetailsComponent implements OnInit {
    
      addToCart(product: Product) {
        this.cartService.addToCart(product);
        window.alert('Your product has been added to the cart!');
      }
    }
    
  3. 修改product-details组件的HTML页面,添加一个Buy按钮,并且绑定click()事件到addToCart()方法。

    <h2>Product Details</h2>
    
    <div *ngIf="product">
        <h3>{{product.name}}</h3>
        <h4>{{product.price | currency}}</h4>
        <p>{{product.description}}</p>
        <button type="button" (click)="addToCart(product)">Buy</button>
    </div>
    
  4. 验证Buy按钮是否工作正常。

    Add To Cart

创建cart组件

  1. 运行如下命令来创建cart组件。

    ng generate component cart
    
  2. 在app-routing.module.ts里为cart组件添加一个新的路由。

    const routes: Routes = [
      { path: '', component: ProductListComponent },
      { path: 'products/:productId', component: ProductDetailsComponent },
      { path: 'cart', component: CartComponent}
    ];
    
  3. 在文件top-bar.component.html里,给Checkout按钮绑定routerLink属性到新增的路由。

    <button type="submit" routerLink="/cart"><img src="assets/images/checkout.png" alt="Checkout" title="Checkout">
        <span>Checkout</span>
    </button>
    
  4. 验证Checkout按钮是否工作正常。

    Checkout

显示购物车详情

  1. 在cart组件类里注入Cart service,并定义一个属性items来获取购物车里的数据。

    export class CartComponent {
      items = this.cartService.getItems();
    
      constructor(
        private readonly cartService: CartService
      ){}
    }
    
  2. 修改HTML页面,显示产品的信息。

    <h3>Cart</h3>
    
    <div class="cart-item" *ngFor="let item of items">
      <span>{{ item.name }}</span>
      <span>{{ item.price | currency }}</span>
    </div>
    
  3. 验证购物车是否工作正常。

    Cart Details

获取运输费用

本章将演示如何使用HttpClient从外部文件来获取运输费用。

  1. 在文件夹assets里创建文件shipping.json,并输入如下数据。

    [    {        "type": "Overnight",        "price": 25.99    },    {        "type": "2-Day",        "price": 9.99    },    {        "type": "Postal",        "price": 2.99    }]
    
  2. 配置AppModule来使用HttpClient。在文件app.module.ts中添加HttpClientModule的引用。

    imports: [
        BrowserModule,
        AppRoutingModule,
        HttpClientModule
      ],
    
  3. 配置cart service以使用HttpClient。在cart service中注入HttpClient。

    constructor(
        private readonly httpClient: HttpClient
      ) { }
    
  4. 配置cart service来获取运输费用数据。在文件cart.service.ts中添加方法getShippingPrices(),使用HttpClient get()方法来获取运输费用数据。

    getShippingPrices() {
        return this.httpClient.get<{ type: string, price: number }[]>('/assets/shipping.json');
      }
    

创建shipping组件

  1. 运行如下命令创建shipping组件。

    ng generate component shipping
    
  2. 在文件app-routing.module.ts中创建新的路由指向shipping组件。

    const routes: Routes = [
      { path: '', component: ProductListComponent },
      { path: 'products/:productId', component: ProductDetailsComponent },
      { path: 'cart', component: CartComponent},
      { path: 'shipping', component: ShippingComponent }
    ];
    
  3. 在文件shipping.component.ts中注入cart service。

    constructor(
        private readonly cartService: CartService
      ) {}
    
  4. 定义一个属性shippingCosts,并使用cart service的getShippingPrices()方法来获取该属性的值。

    export class ShippingComponent {
      shippingCosts!: Observable<{ type: string, price: number }[]>;
    
      constructor(
        private readonly cartService: CartService
      ) {}
    
      ngOnInit(): void {
        this.shippingCosts = this.cartService.getShippingPrices();
      }
    }
    
  5. 更新shipping组件的HTML文件,显示运输的类型和价格。

    <h3>Shipping Prices</h3>
    
    <div class="shippingItem" *ngFor="let item of shippingCosts | async">
        <span>{{item.type}}</span>
        <span>{{item.price | currency}}</span>
    </div>
    
  6. 在cart组件添加一个链接,用来跳转到shipping组件。

    <p>
        <a routerLink="/shipping">Shipping Prices</a>
    </p>
    
  7. 最终的效果如下图。

    Cart List

    Shipping Prices