填写这份《一分钟调查》,帮我们(开发组)做得更好!去填写Home

管理数据

Managing Data

路由的末尾,本应用实现了一个包含两个视图的商品名录:商品列表和商品详情。用户点击清单中的某个商品名称,就会在新视图中看到具有专门的 URL 或路由的详情页。

At the end of Routing, the online store application has a product catalog with two views: a product list and product details. Users can click on a product name from the list to see details in a new view, with a distinct URL, or route.

本页将指导你分三个步骤创建购物车:

This page guides you through creating the shopping cart in three phases:

  • 修改商品详情页,让它包含一个 “Buy” 按钮,它会把当前商品添加到由 "购物车服务" 管理的商品列表中。

    Update the product details page to include a "Buy" button, which adds the current product to a list of products that a cart service manages.

  • 添加一个购物车组件,它会显示购物车中的商品。

    Add a cart component, which displays the items in the cart.

  • 添加一个配送组件,它会使用 Angular 的 HttpClient.json 文件中检索配送数据来取得购物车中这些商品的运费。

    Add a shipping component, which retrieves shipping prices for the items in the cart by using Angular's HttpClient to retrieve shipping data from a .json file.

服务

Services

服务是 Angular 应用的重要组成部分。在 Angular 中,服务是一个类的实例,它可以借助 Angular 的依赖注入系统来让应用中的任何一个部件都能使用它。

Services are an integral part of Angular applications. In Angular, a service is an instance of a class that you can make available to any part of your application using Angular's dependency injection system.

服务可以让你在应用的各个部件之间共享数据。对于在线商店,购物车服务就是存放购物车的数据和方法的地方。

Services are the place where you share data between parts of your application. For the online store, the cart service is where you store your cart data and methods.

创建购物车服务

Create the shopping cart service

到目前为止,用户可以查看商品信息、模拟共享,并接收商品变化的通知。但是,无法购买商品。

Up to this point, users can view product information, and simulate sharing and being notified about product changes. They cannot, however, buy products.

在本节中,你将在商品详情页中添加“Buy”按钮。你还可以设置一个购物车服务来存储购物车中商品的相关信息。

In this section, you add a "Buy" button to the product details page and set up a cart service to store information about products in the cart.

稍后,在本教程的表单部分,也会从用户的结账页面中访问这个 购物车服务。

Later, the Forms part of this tutorial guides you through accessing this cart service from the page where the user checks out.

定义购物车服务

Define a cart service

  1. 生成购物车服务。

    Generate a cart service.

    1. 右键单击 app 文件夹,选择 Angular Generator,然后选择 Service。把新的服务命名为 cart

      Right click on the app folder, choose Angular Generator, and choose Service. Name the new service cart.

      import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class CartService { constructor() {} }
      src/app/cart.service.ts
            
            import { Injectable } from '@angular/core';
      
      @Injectable({
        providedIn: 'root'
      })
      export class CartService {
      
        constructor() {}
      
      }
          
    2. StackBlitz 可能会生成不带 {provedIn:'root'} 语句的 @Injectable() 装饰器。相反,此生成器默认会在 app.module.ts 中提供购物车服务。对于本教程来说,任何一种都可以。 不过 @Injectable(){provedIn:'root'} 语法支持摇树优化,但本章不展开讲。

      StackBlitz might generate the @Injectable() decorator without the { providedIn: 'root' } statement as above. Instead, the generator provides the cart service in app.module.ts by default. For the purposes of this tutorial, either way works. The @Injectable() { providedIn: 'root' } syntax allows tree shaking, which is beyond the scope of this guide.

  2. CartService 类中,定义一个 items 属性来把当前商品的数组存储在购物车中。

    In the CartService class, define an items property to store the array of the current products in the cart.

    export class CartService { items = []; }
    src/app/cart.service.ts
          
          export class CartService {
      items = [];
    }
        
  3. 定义把商品添加到购物车、返回购物车商品以及清除购物车商品的方法:

    Define methods to add items to the cart, return cart items, and clear the cart items:

    export class CartService { items = []; addToCart(product) { this.items.push(product); } getItems() { return this.items; } clearCart() { this.items = []; return this.items; } }
    src/app/cart.service.ts
          
          export class CartService {
      items = [];
    
      addToCart(product) {
        this.items.push(product);
      }
    
      getItems() {
        return this.items;
      }
    
      clearCart() {
        this.items = [];
        return this.items;
      }
    }
        
    • addToCart() 方法会将产品附加到 items 数组中。

      The addToCart() method appends a product to an array of items.

    • getItems() 方法会收集用户加到购物车中的商品,并返回每个商品及其数量。

      The getItems() method collects the items users add to the cart and returns each item with its associated quantity.

    • clearCart() 方法返回一个空数组。

      The clearCart() method returns an empty array of items.

使用购物车服务

Use the cart service

本节会教你通过 “Buy” 按钮使用购物车服务来把商品添加到购物车。

This section walks you through using the cart service to add a product to the cart with a "Buy" button.

  1. 打开 product-details.component.ts

    Open product-details.component.ts.

  2. 配置该组件,使其能使用这个购物车服务。

    Configure the component to use the cart service.

    1. 导入购物车服务。

      Import the cart service.

      import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { products } from '../products'; import { CartService } from '../cart.service';
      src/app/product-details/product-details.component.ts
            
            import { Component, OnInit } from '@angular/core';
      import { ActivatedRoute } from '@angular/router';
      
      import { products } from '../products';
      import { CartService } from '../cart.service';
          
    2. 通过把购物车服务注入到这里的 constructor() 中来注入它。

      Inject the cart service by adding it to the constructor().

      export class ProductDetailsComponent implements OnInit { constructor( private route: ActivatedRoute, private cartService: CartService ) { } }
      src/app/product-details/product-details.component.ts
            
            export class ProductDetailsComponent implements OnInit {
        constructor(
          private route: ActivatedRoute,
          private cartService: CartService
        ) { }
      }
          
  3. 定义 addToCart() 方法,该方法会当前商品添加到购物车中。

    Define the addToCart() method, which adds the current product to the cart.

    addToCart() 方法会做下面这三件事:

    The addToCart() method does the following three things:

    • 接收当前的 product

      Receives the current product.

    • 使用购物车服务的 addToCart() 方法把该商品添加到购物车中。

      Uses the cart service's addToCart() method to add the product the cart.

    • 显示一条消息,表明你已经把一个商品加入了购物车。

      Displays a message that you've added a product to the cart.

      export class ProductDetailsComponent implements OnInit { addToCart(product) { window.alert('Your product has been added to the cart!'); this.cartService.addToCart(product); } }
      src/app/product-details/product-details.component.ts
            
            export class ProductDetailsComponent implements OnInit {
        addToCart(product) {
          window.alert('Your product has been added to the cart!');
          this.cartService.addToCart(product);
        }
      }
          
  4. 修改商品详情模板,让它具有一个“Buy”按钮,用于把当前商品添加到购物车中。

    Update the product details template with a "Buy" button that adds the current product to the cart.

    1. 打开 product-details.component.html

      Open product-details.component.html.

    2. 添加一个标签为“Buy”的按钮,并把其 click() 事件绑定到 addToCart() 方法:

      Add a button with the label "Buy", and bind the click() event to the addToCart() method:

      <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>
      src/app/product-details/product-details.component.html
            
            <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>
          
  5. 要查看新的“Buy”按钮,请刷新应用并单击商品名称以显示其详细信息。

    To see the new "Buy" button, refresh the application and click on a product's name to display its details.

  6. 点击“Buy”按钮来把该商品添加到购物车中存储的商品列表中,并显示一条确认消息。

    Click the "Buy" button to add the product to the stored list of items in the cart and display a confirmation message.

创建购物车页面

Create the cart page

此时,用户可以通过点击“Buy”来把商品放入购物车,但他们还看不到购物车。

At this point, users can put items in the cart by clicking "Buy", but they can't yet see their cart.

分两步创建购物车页面:

Create the cart page in two steps:

  1. 创建一个购物车组件并配置指向这个新组件的路由。此时,购物车页面只会显示默认文本。

    Create a cart component and configure routing to the new component. At this point, the cart page will only have default text.

  2. 显示购物车商品

    Display the cart items.

设置该组件

Set up the component

要创建购物车页面,首先要执行与创建商品详情组件相同的步骤,并为这个新组件设置路由。

To create the cart page, begin by following the same steps you did to create the product details component and configure routing for the new component.

  1. 生成一个名叫 cart 的购物车组件。

    Generate a cart component, named cart.

    提示:在文件列表框中,右键单击 app 文件夹,选择 Angular GeneratorComponent

    Reminder: In the file list, right-click the app folder, choose Angular Generator and Component.

    import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-cart', templateUrl: './cart.component.html', styleUrls: ['./cart.component.css'] }) export class CartComponent implements OnInit { constructor() { } ngOnInit() { } }
    src/app/cart/cart.component.ts
          
          import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'app-cart',
      templateUrl: './cart.component.html',
      styleUrls: ['./cart.component.css']
    })
    export class CartComponent implements OnInit {
    
      constructor() { }
    
      ngOnInit() {
      }
    
    }
        
  2. 为购物车组件添加路由(URL 模式)。

    Add routing (a URL pattern) for the cart component.

    打开 app.module.ts,为组件 CartComponent 添加一个路由,其路由为 cart

    Open app.module.ts and add a route for the component CartComponent, with a path of cart:

    @NgModule({ imports: [ BrowserModule, ReactiveFormsModule, RouterModule.forRoot([ { path: '', component: ProductListComponent }, { path: 'products/:productId', component: ProductDetailsComponent }, { path: 'cart', component: CartComponent }, ]) ],
    src/app/app.module.ts
          
          @NgModule({
      imports: [
        BrowserModule,
        ReactiveFormsModule,
        RouterModule.forRoot([
          { path: '', component: ProductListComponent },
          { path: 'products/:productId', component: ProductDetailsComponent },
          { path: 'cart', component: CartComponent },
        ])
      ],
        
    1. 要查看新的购物车组件,请点击“Checkout”按钮。你会看到默认文本“cart works!”,该 URL 的格式为 https://getting-started.stackblitz.io/cart,其中的 getting-started.stackblitz.io 部分可能与你的 StackBlitz 项目不同。

      To see the new cart component, click the "Checkout" button. You can see the "cart works!" default text, and the URL has the pattern https://getting-started.stackblitz.io/cart, where getting-started.stackblitz.io may be different for your StackBlitz project.

      “Checkout” 按钮的起始代码已经在顶栏组件中包含了一个指向 /cartrouterLink

      The starter code for the "Checkout" button already includes a routerLink for /cart the top-bar component.

显示购物车商品

Display the cart items

你可以用服务来跨组件共享数据:

You can use services to share data across components:

  • 商品详情组件已经使用了购物车服务( CartService )来把商品添加到购物车中。

    The product details component already uses the cart service to add products to the cart.

  • 本节将告诉你如何修改购物车组件以使用购物车服务来显示购物车中的商品。

    This section shows you how to use the cart service to display the products in the cart.

  1. 打开 cart.component.ts

    Open cart.component.ts.

  2. 设置该组件是为了让它能够使用这个购物车服务。(这与你在前面设置商品详情组件以使用购物车服务的方式是一样的。)

    Configure the component to use the cart service.

    1. cart.service.ts 文件中导入 CartService

      Import the CartService from the cart.service.ts file.

      import { Component } from '@angular/core'; import { CartService } from '../cart.service';
      src/app/cart/cart.component.ts
            
            import { Component } from '@angular/core';
      import { CartService } from '../cart.service';
          
    2. 注入 CartService,以便购物车组件可以使用它。

      Inject the CartService so that the cart component can use it.

      export class CartComponent { constructor( private cartService: CartService ) { } }
      src/app/cart/cart.component.ts
            
            export class CartComponent {
      
        constructor(
          private cartService: CartService
        ) { }
      }
          
  3. 定义 items 属性,以便把商品存放在购物车中。

    Define the items property to store the products in the cart.

    export class CartComponent { items; constructor( private cartService: CartService ) { } }
    src/app/cart/cart.component.ts
          
          export class CartComponent {
      items;
    
      constructor(
        private cartService: CartService
      ) { }
    }
        
  4. 使用购物车服务的 getItems() 方法设置这些商品。回想一下,你在生成 cart.service.ts定义过这个方法。

    Set the items using the cart service's getItems() method. Recall that you defined this method when you generated cart.service.ts.

    所生成的 CartComponent 类是这样的:

    The resulting CartComponent class is as follows:

    export class CartComponent implements OnInit { items; constructor( private cartService: CartService ) { } ngOnInit() { this.items = this.cartService.getItems(); } }
    src/app/cart/cart.component.ts
          
          export class CartComponent implements OnInit {
      items;
    
      constructor(
        private cartService: CartService
      ) { }
    
      ngOnInit() {
        this.items = this.cartService.getItems();
      }
    }
        
  5. 修改模板,加上标题,用带有 *ngFor<div> 来显示每个购物车商品的名字和价格。

    Update the template with a header, and use a <div> with an *ngFor to display each of the cart items with its name and price.

    生成的 CartComponent 模板如下:

    The resulting CartComponent template is as follows:

    <h3>Cart</h3> <div class="cart-item" *ngFor="let item of items"> <span>{{ item.name }}</span> <span>{{ item.price | currency }}</span> </div>
    src/app/cart/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>
        
  6. 测试你的购物车组件。

    Test your cart component.

    1. 点击“My Store”,进入商品列表页面。

      Click on "My Store" to go to the product list page.

    2. 单击商品名称以显示其详细信息。

      Click on a product name to display its details.

    3. 点击“Buy”,即可将商品添加到购物车。

      Click "Buy" to add the product to the cart.

    4. 点击“Checkout”查看购物车。

      Click "Checkout" to see the cart.

    5. 要添加其它商品,请点击“My Store”返回商品列表。

      To add another product, click "My Store" to return to the product list.

    重复上述步骤来添加更多条目。

    Repeat to add more items to the cart.

StackBlitz 提示:只要预览刷新,就会清除购物车。如果你对该应用进行了更改,页面就会刷新,你需要重新购买商品来填充购物车。

StackBlitz tip: Any time the preview refreshes, the cart is cleared. If you make changes to the app, the page refreshes, so you'll need to buy products again to populate the cart.

要了解关于服务的更多信息,请参阅“服务和依赖注入简介”

For more information about services, see Introduction to Services and Dependency Injection.

检索运费价格

Retrieve shipping prices

服务器通常采用流的形式返回数据。 流是很有用的,因为它们可以很容易地转换返回的数据,也可以修改你请求数据的方式。 Angular 的 HTTP 客户端( HttpClient )是一种内置的方式,可以从外部 API 中获取数据,并以流的形式提供给你的应用。

Servers often return data in the form of a stream. Streams are useful because they make it easy to transform the returned data and make modifications to the way you request that data. The Angular HTTP client, HttpClient, is a built-in way to fetch data from external APIs and provide them to your app as a stream.

本节会为你展示如何使用 HTTP 客户端从外部文件中检索运费。

This section shows you how to use the HTTP client to retrieve shipping prices from an external file.

预定义的配送数据

Predefined shipping data

在本指南的 StackBlitz 应用中,通过 assets/shipping.json 文件提供了一些预定义的配送数据。你可以利用这些数据为购物车中的商品添加运费。

The app StackBlitz generates for this guide comes with predefined shipping data in assets/shipping.json. Use this data to add shipping prices for items in the cart.

[ { "type": "Overnight", "price": 25.99 }, { "type": "2-Day", "price": 9.99 }, { "type": "Postal", "price": 2.99 } ]
src/assets/shipping.json
      
      [
  {
    "type": "Overnight",
    "price": 25.99
  },
  {
    "type": "2-Day",
    "price": 9.99
  },
  {
    "type": "Postal",
    "price": 2.99
  }
]
    

AppModule 中为应用启用 HttpClient

Use HttpClient in the AppModule

在使用 Angular 的 HTTP 客户端之前,你必须先配置你的应用来使用 HttpClientModule

Before you can use Angular's HTTP client, you must configure your app to use HttpClientModule.

Angular 的 HttpClientModule 中注册了在整个应用中使用 HttpClient 服务的单个实例所需的服务提供者。

Angular's HttpClientModule registers the providers your app needs to use a single instance of the HttpClient service throughout your app.

  1. 打开 app.module.ts

    Open app.module.ts.

    该文件包含可供整个应用使用的导入对象和功能。

    This file contains imports and functionality that is available to the entire app.

  2. 在该文件的顶部从 @angular/common/http 包中导入 HttpClientModule 以及其它导入项。 由于有很多其它导入项,因此这里的代码片段省略它们,以保持简洁。请确保现有的导入都还在原地。

    Import HttpClientModule from the @angular/common/http package at the top of the file with the other imports. As there are a number of other imports, this code snippet omits them for brevity. Be sure to leave the existing imports in place.

    import { HttpClientModule } from '@angular/common/http';
    src/app/app.module.ts
          
          import { HttpClientModule } from '@angular/common/http';
        
  3. HttpClientModule 添加到 AppModule @NgModule()imports 数组中,以便全局注册 Angular 的 HttpClient

    Add HttpClientModule to the AppModule @NgModule() imports array to register Angular's HttpClient providers globally.

    @NgModule({ imports: [ BrowserModule, HttpClientModule, 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 { }
    src/app/app.module.ts
          
          @NgModule({
      imports: [
        BrowserModule,
        HttpClientModule,
        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 { }
        

在购物车服务中使用 HttpClient

Use HttpClient in the cart service

AppModule 已经导入了 HttpClientModule,接下来就是将 HttpClient 服务注入到你的服务中,以便此应用可以获取数据并与外部 API 和资源进行交互。

Now that the AppModule imports the HttpClientModule, the next step is to inject the HttpClient service into your service so your app can fetch data and interact with external APIs and resources.

  1. 打开 cart.service.ts

    Open cart.service.ts.

  2. @angular/common/http 包中导入 HttpClient

    Import HttpClient from the @angular/common/http package.

    import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http';
    src/app/cart.service.ts
          
          import { Injectable } from '@angular/core';
    
    import { HttpClient } from '@angular/common/http';
        
  3. HttpClient 注入到 CartService 的构造函数中:

    Inject HttpClient into the CartService constructor:

    export class CartService { items = []; constructor( private http: HttpClient ) {} }
    src/app/cart.service.ts
          
          export class CartService {
      items = [];
    
      constructor(
        private http: HttpClient
      ) {}
    }
        

定义 get() 方法

Define the get() method

多个组件可以使用同一个服务。在这个教程的后半部分,商品配送组件使用该购物车服务从 shipping.json 文件中借助 HTTP 检索配送数据。 首先要定义一个 get() 方法。

Multiple components can leverage the same service. Later in this tutorial, the shipping component uses the cart service to retrieve shipping data via HTTP from the shipping.json file. First, define a get() method.

  1. 继续在 cart.service.ts 中工作。

    Continue working in cart.service.ts.

  2. clearCart() 方法下面,定义一个新的 getShippingPrices() 方法,该方法使用 HttpClient#get() 方法检索配送数据(类型和价格)。

    Below the clearCart() method, define a new getShippingPrices() method that uses the HttpClient get() method to retrieve the shipping data.

    export class CartService { items = []; constructor( private http: HttpClient ) {} addToCart(product) { this.items.push(product); } getItems() { return this.items; } clearCart() { this.items = []; return this.items; } getShippingPrices() { return this.http.get('/assets/shipping.json'); } }
    src/app/cart.service.ts
          
          export class CartService {
      items = [];
    
      constructor(
        private http: HttpClient
      ) {}
    
      addToCart(product) {
        this.items.push(product);
      }
    
      getItems() {
        return this.items;
      }
    
      clearCart() {
        this.items = [];
        return this.items;
      }
    
      getShippingPrices() {
        return this.http.get('/assets/shipping.json');
      }
    }
        

要了解关于 Angular HttpClient 的更多信息,请参阅HttpClient 指南

For more information about Angular's HttpClient, see HttpClient.

定义配送页面

Define the shipping page

现在你的应用已经可以检索配送数据了,你还要创建一个配送组件和相关的模板。

Now that your app can retrieve shipping data, create a shipping component and template.

  1. 生成一个名为 shipping 的新组件。

    Generate a new component named shipping.

    提示:在文件列表框中,右键单击 app 文件夹,选择 Angular GeneratorComponent

    Reminder: In the file list, right-click the app folder, choose Angular Generator and Component.

    import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-shipping', templateUrl: './shipping.component.html', styleUrls: ['./shipping.component.css'] }) export class ShippingComponent implements OnInit { constructor() { } ngOnInit() { } }
    src/app/shipping/shipping.component.ts
          
          import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'app-shipping',
      templateUrl: './shipping.component.html',
      styleUrls: ['./shipping.component.css']
    })
    export class ShippingComponent implements OnInit {
    
      constructor() { }
    
      ngOnInit() {
      }
    
    }
        
  2. app.module.ts 中,添加一个配送路由。其 pathshipping,其 component 为 ShippingComponent

    In app.module.ts, add a route for shipping. Specify a path of shipping and a component of ShippingComponent.

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

    新的配送组件尚未链接到任何其它组件,但你可以通过输入其路由指定的 URL 在预览窗格中看到它的模板。该 URL 具有以下模式:https://getting-started.stackblitz.io/shipping,其中的 gets-started.stackblitz.io 部分可能与你的 StackBlitz 项目不同。

    There's no link to the new shipping component yet, but you can see its template in the preview pane by entering the URL its route specifies. The URL has the pattern: https://getting-started.stackblitz.io/shipping where the getting-started.stackblitz.io part may be different for your StackBlitz project.

  3. 修改配送组件,让它利用购物车服务从 shipping.json 文件中通过 HTTP 检索配送数据。

    Modify the shipping component so it uses the cart service to retrieve shipping data via HTTP from the shipping.json file.

    1. 导入购物车服务。

      Import the cart service.

      import { Component, OnInit } from '@angular/core'; import { CartService } from '../cart.service';
      src/app/shipping/shipping.component.ts
            
            import { Component, OnInit } from '@angular/core';
      
      import { CartService } from '../cart.service';
          
    2. 定义 shippingCosts 属性。

      Define a shippingCosts property.

      export class ShippingComponent implements OnInit { shippingCosts; }
      src/app/shipping/shipping.component.ts
            
            export class ShippingComponent implements OnInit {
        shippingCosts;
      }
          
    3. 把购物车服务注入到 ShippingComponent 的构造函数中:

      Inject the cart service in the ShippingComponent constructor:

      constructor( private cartService: CartService ) { }
      src/app/shipping/shipping.component.ts
            
            constructor(
        private cartService: CartService
      ) {
      }
          
    4. 利用购物车服务的 getShippingPrices() 方法设置 shippingCosts 属性。

      Set the shippingCosts property using the getShippingPrices() method from the cart service.

      export class ShippingComponent implements OnInit { shippingCosts; constructor( private cartService: CartService ) { } ngOnInit() { this.shippingCosts = this.cartService.getShippingPrices(); } }
      src/app/shipping/shipping.component.ts
            
            export class ShippingComponent implements OnInit {
        shippingCosts;
      
        constructor(
          private cartService: CartService
        ) {
        }
      
        ngOnInit() {
          this.shippingCosts = this.cartService.getShippingPrices();
        }
      
      }
          
  4. 利用 async 管道修改配送组件的模板,以显示配送类型和价格:

    Update the shipping component's template to display the shipping types and prices using the async pipe:

    <h3>Shipping Prices</h3> <div class="shipping-item" *ngFor="let shipping of shippingCosts | async"> <span>{{ shipping.type }}</span> <span>{{ shipping.price | currency }}</span> </div>
    src/app/shipping/shipping.component.html
          
          <h3>Shipping Prices</h3>
    
    <div class="shipping-item" *ngFor="let shipping of shippingCosts | async">
      <span>{{ shipping.type }}</span>
      <span>{{ shipping.price | currency }}</span>
    </div>
        

    async 管道从数据流中返回最新值,并在所属组件的生命期内持续返回。当 Angular 销毁该组件时,async 管道会自动停止。有关 async 管道的详细信息,请参见 AsyncPipe API 文档

    The async pipe returns the latest value from a stream of data and continues to do so for the life of a given component. When Angular destroys that component, the async pipe automatically stops. For detailed information about the async pipe , see the AsyncPipe API documentation.

  5. 在购物车页面中添加一个到配送页面的链接:

    Add a link from the cart page to the shipping page:

    <h3>Cart</h3> <p> <a routerLink="/shipping">Shipping Prices</a> </p> <div class="cart-item" *ngFor="let item of items"> <span>{{ item.name }}</span> <span>{{ item.price | currency }}</span> </div>
    src/app/cart/cart.component.html
          
          <h3>Cart</h3>
    
    <p>
      <a routerLink="/shipping">Shipping Prices</a>
    </p>
    
    <div class="cart-item" *ngFor="let item of items">
      <span>{{ item.name }}</span>
      <span>{{ item.price | currency }}</span>
    </div>
        
  6. 测试这个运费价格功能:

    Test your shipping prices feature:

    点击“Checkout”按钮,查看更新后的购物车。(注意,修改应用会导致预览窗格刷新,这会清空购物车。)

    Click the "Checkout" button to see the updated cart. Remember that changing the app causes the preview to refresh, which empties the cart.

    点击此链接可以导航到运费页。

    Click on the link to navigate to the shipping prices.

下一步

Next steps

恭喜!你有一个带有商品名录和购物车的在线商店应用了,而且你还可以查询并显示运费。

Congratulations! You have an online store application with a product catalog and shopping cart. You can also look up and display shipping prices.

要继续探索 Angular,请选择下列选项之一:

To continue exploring Angular, choose either of the following options: