Hướng dẫn này được xây dựng dựa trên bước thứ hai của hướng dẫn Bắt đầu với ứng dụng Angular cơ bản đó là Thêm điều hướng vào ứng dụng Angular.
Ở giai đoạn phát triển này, ứng dụng cửa hàng có danh mục sản phẩm với hai view là: danh sách sản phẩm và chi tiết sản phẩm.
Người dùng có thể nhấp vào tên sản phẩm từ danh sách để xem thông tin chi tiết sản phẩm trong view mới, với một URL hoặc tuyến đường riêng biệt.
Bước này của hướng dẫn sẽ hướng dẫn bạn cách tạo giỏ hàng theo các giai đoạn sau:
HttpClient
của Angular để truy xuất dữ liệu vận chuyển từ tệp .json
.Trong Angular, một dịch vụ là một instance của một lớp mà bạn có thể cung cấp cho bất kỳ phần nào trong ứng dụng của mình bằng cách sử dụng dependency injection của Angular.
Hiện tại, người dùng có thể xem thông tin sản phẩm, đồng thời ứng dụng có thể giả lập chia sẻ và thông báo về các thay đổi của sản phẩm.
Bước tiếp theo là xây dựng cách để người dùng thêm sản phẩm vào giỏ hàng. Phần này hướng dẫn bạn thêm nút Buy và thiết lập dịch vụ giỏ hàng để lưu trữ thông tin về các sản phẩm trong giỏ hàng.
1. Để tạo dịch vụ giỏ hàng, nhấp chuột phải vào thư mục app
, chọn Angular Generator và chọn Service. Đặt tên cho dịch vụ mới là cart
.
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class CartService {
constructor() {}
}
2. Import interface Product
từ ./products.js
.
3. Trong lớp CartService
, định nghĩa thuộc tính items
để lưu trữ mảng các sản phẩm hiện tại trong giỏ hàng.
import { Product } from './products';
/* . . . */
export class CartService {
items: Product[] = [];
/* . . . */
}
4. Định nghĩa các phương thức để thêm các mặt hàng vào giỏ hàng, trả lại các mặt hàng trong giỏ hàng và xóa các mặt hàng trong giỏ hàng.
export class CartService {
items: Product[] = [];
/* . . . */
addToCart(product: Product) {
this.items.push(product);
}
getItems() {
return this.items;
}
clearCart() {
this.items = [];
return this.items;
}
/* . . . */
}
addToCart()
sẽ thêm một sản phẩm vào giỏ hàng.getItems()
sẽ trả về tất cả mặt hàng có trong giỏ hàng.clearCart()
sẽ xóa tất cả mặt hàng trong giỏ hàng.Phần này sẽ hướng dẫn bạn cách sử dụng CartService
để thêm sản phẩm vào giỏ hàng.
1. Import các thành phần sau vào trong file 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';
2. Inject dịch vụ giỏ hàng bằng cách thêm nó vào phương thức constructor()
.
export class ProductDetailsComponent implements OnInit {
constructor(
private route: ActivatedRoute,
private cartService: CartService
) { }
}
3. Định nghĩa phương thức addToCart()
để thêm sản phẩm hiện tại vào giỏ hàng.
export class ProductDetailsComponent implements OnInit {
addToCart(product: Product) {
this.cartService.addToCart(product);
window.alert('Your product has been added to the cart!');
}
}
Phương thức addToCart()
sẽ làm những việc sau đây:
product
hiện tại làm tham số đầu vào.addToCart()
của CartService
để thêm sản phẩm vào giỏ hàng.4. Trong file template product-details.component.html
, thêm nút Buy và liên kết sự kiện click()
với phương thức addToCart()
. Mã này thêm nút Buy vào template chi tiết sản phẩm để thêm sản phẩm hiện tại vào giỏ hàng.
<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. Kiểm tra nút Buy bằng cách làm mới ứng dụng và nhấp vào tên sản phẩm để hiển thị thông tin chi tiết sản phẩm.
6. Nhấn nút Buy để thêm sản phẩm vào giỏ hàng và hiển thị thông báo xác nhận.
Để khách hàng xem giỏ hàng của họ, bạn có thể tạo view giỏ hàng theo hai bước:
Để tạo view giỏ hàng, hãy làm theo các bước tương tự bạn đã làm để tạo ProductDetailsComponent
và cấu hình định tuyến cho component mới.
1. Tạo component giỏ hàng được đặt tên cart
bằng cách nhấp chuột phải vào thư mục app
, chọn Angular Generator và Component.
import { Component } from '@angular/core';
@Component({
selector: 'app-cart',
templateUrl: './cart.component.html',
styleUrls: ['./cart.component.css']
})
export class CartComponent {
constructor() { }
}
StackBlitz cũng tạo ngOnInit()
theo mặc định trong các component. Bạn có thể bỏ qua ngOnInit()
của CartComponent
trong hướng dẫn này.
2. Mở file app.module.ts
và thêm một tuyến đường cho component CartComponent
, với path
là cart
và component là CartComponent
.
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule,
RouterModule.forRoot([
{ path: '', component: ProductListComponent },
{ path: 'products/:productId', component: ProductDetailsComponent },
{ path: 'cart', component: CartComponent },
])
],
3. Cập nhật nút Checkout để nó định tuyến đến URL /cart
. Trong top-bar.component.html
, thêm directive routerLink
trỏ đến /cart
.
<a routerLink="/cart" class="button fancy-button">
<i class="material-icons">shopping_cart</i>Checkout
</a>
4. Kiểm tra CartComponent
bằng cách nhấp vào nút Checkout. Bạn có thể thấy "cart works!" và URL có dạng https://getting-started.stackblitz.io/cart
. Domain getting-started.stackblitz.io
có thể khác đối với dự án StackBlitz của bạn.
Phần này hướng dẫn bạn cách sử dụng dịch vụ giỏ hàng để hiển thị các sản phẩm trong giỏ hàng.
1. Import các thành phần sau trong file cart.component.ts
.
import { Component } from '@angular/core';
import { CartService } from '../cart.service';
2. Inject CartService
để CartComponent
có thể sử dụng nó bằng cách thêm nó vào phương thức constructor()
.
export class CartComponent {
constructor(
private cartService: CartService
) { }
}
3. Định nghĩa thuộc tính items
để lưu trữ các sản phẩm trong giỏ hàng.
export class CartComponent {
items = this.cartService.getItems();
constructor(
private cartService: CartService
) { }
}
Mã này gán giá trị cho thuộc tính items
bằng cách sử dụng phương thức getItems()
của CartService
. Bạn đã định nghĩa phương thức này khi bạn tạo cart.service.ts
.
4. Cập nhật template của giỏ hàng với tiêu đề và sử dụng thẻ <div>
với directive *ngFor
để hiển thị từng phần tử trong giỏ hàng với tên và giá của nó. Template của CartComponent
trông sẽ như sau.
<h3>Cart</h3>
<div class="cart-item" *ngFor="let item of items">
<span>{{ item.name }}</span>
<span>{{ item.price | currency }}</span>
</div>
5. Kiểm tra giỏ hàng của bạn hoạt động như mong đợi:
Để biết thêm thông tin về các dịch vụ, hãy xem Giới thiệu về Dịch vụ và Dependency Injection.
Máy chủ thường trả về dữ liệu dưới dạng stream. Stream rất hữu ích vì chúng giúp bạn dễ dàng chuyển đổi dữ liệu trả về và thực hiện sửa đổi theo cách bạn yêu cầu dữ liệu đó. Angular HttpClient
là một cách tích hợp để tìm nạp dữ liệu từ các API bên ngoài và cung cấp chúng cho ứng dụng của bạn dưới dạng stream.
Phần này hướng dẫn bạn cách sử dụng HttpClient
để lấy phí vận chuyển từ tệp bên ngoài.
Ứng dụng mà StackBlitz tạo cho hướng dẫn này đi kèm với dữ liệu vận chuyển được định nghĩa trước trong file assets/shipping.json
. Sử dụng dữ liệu này để tính phí vận chuyển cho các mặt hàng trong giỏ hàng.
[
{
"type": "Overnight",
"price": 25.99
},
{
"type": "2-Day",
"price": 9.99
},
{
"type": "Postal",
"price": 2.99
}
]
Để sử dụng Angular HttpClient
, bạn phải cấu hình ứng dụng của mình để sử dụng HttpClientModule
.
HttpClientModule
của Angular đăng ký các nhà cung cấp mà ứng dụng của bạn cần để sử dụng dịch vụ HttpClient
trong suốt ứng dụng của bạn.
1. Trong file app.module.ts
, import HttpClientModule
từ gói @angular/common/http
ở đầu tệp cùng với các import khác. Vì có một số import khác, đoạn mã này bỏ qua chúng cho ngắn gọn. Đảm bảo giữ nguyên các import hiện có.
import { HttpClientModule } from '@angular/common/http';
Để đăng ký các nhà cung cấp HttpClient
của Angular trên toàn cầu, hãy thêm HttpClientModule
vào mảng AppModule @NgModule() imports
.
@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 { }
Bước tiếp theo là đưa dịch vụ HttpClient
vào dịch vụ của bạn để ứng dụng của bạn có thể tìm nạp dữ liệu và tương tác với các tài nguyên và API bên ngoài.
1. Trong filecart.service.ts
, import HttpClient
từ gói @angular/common/http
.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Product } from './products';
2. Inject HttpClient
vào phương thức constructor()
của CartService
.
export class CartService {
items: Product[] = [];
constructor(
private http: HttpClient
) {}
/* . . . */
}
Để nhận dữ liệu vận chuyển từ file shipping.json
, Bạn có thể sử dụng phương thức get()
của HttpClient
.
1. Trong file cart.service.ts
, bên dưới phương thức clearCart()
, hãy định nghĩa phương thức getShippingPrices()
mới sử dụng phương thức get()
của HttpClient
.
export class CartService {
/* . . . */
getShippingPrices() {
return this.http.get<{type: string, price: number}[]>('/assets/shipping.json');
}
}
Để biết thêm thông tin về Angular HttpClient
, hãy xem hướng dẫn Tương tác Client-Server.
Bây giờ bạn đã cấu hình ứng dụng của mình để truy xuất dữ liệu vận chuyển, bạn có thể tạo một nơi để hiển thị dữ liệu đó.
1. Tạo một component mới được đặt tên là shipping
bằng cách nhấp chuột phải vào thư mục app
, chọn Angular Generator và chọn Component.
import { Component } from '@angular/core';
@Component({
selector: 'app-shipping',
templateUrl: './shipping.component.html',
styleUrls: ['./shipping.component.css']
})
export class ShippingComponent {
constructor() { }
}
2. Trong file app.module.ts
, thêm một tuyến đường cho phí vận chuyển. Thêm path
là shipping
và một component
là 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 { }
Chưa có liên kết đến component vận chuyển mới, nhưng bạn có thể xem template của nó trong ô xem trước bằng cách nhập URL mà tuyến đường của nó chỉ định. URL có dạng: https://getting-started.stackblitz.io/shipping
trong đó domain getting-started.stackblitz.io
có thể khác đối với dự án StackBlitz của bạn.
Phần này hướng dẫn bạn cách sửa đổi ShippingComponent
để truy xuất dữ liệu vận chuyển qua HTTP từ tệp shipping.json
.
1. Trong tệp shipping.component.ts
, import CartService
như sau.
import { Component } from '@angular/core';
import { CartService } from '../cart.service';
2. Chèn dịch vụ giỏ hàng trong phương thức constructor()
của ShippingComponent
.
constructor(private cartService: CartService) {
}
3. Định nghĩa thuộc tính shippingCosts
, gán giá trị cho thuộc tính shippingCosts
bằng cách sử dụng phương thức getShippingPrices()
từ CartService
.
export class ShippingComponent {
shippingCosts = this.cartService.getShippingPrices();
}
4. Cập nhật template của ShippingComponent
để hiển thị danh sách phí vận chuyển bằng cách sử dụng đường ống async
.
<h3>Shipping Prices</h3>
<div class="shipping-item" *ngFor="let shipping of shippingCosts | async">
<span>{{ shipping.type }}</span>
<span>{{ shipping.price | currency }}</span>
</div>
Đường ống async
trả về giá trị mới nhất từ một luồng dữ liệu và tiếp tục làm như vậy cho vòng đời của một component nhất định. Khi Angular hủy component đó, đường ống async
sẽ tự động dừng lại. Để biết thông tin chi tiết về đường ống async
, hãy xem tài liệu API AsyncPipe.
5. Thêm một liên kết từ màn hình CartComponent
đến màn hình ShippingComponent
.
<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. Nhấp vào nút Checkout để xem giỏ hàng đã được cập nhật. Hãy nhớ rằng việc thay đổi ứng dụng sẽ làm mới bản xem trước, làm trống giỏ hàng.
Nhấp vào liên kết để điều hướng đến trang bảng giá vận chuyển.
Bây giờ bạn có một ứng dụng cửa hàng với danh mục sản phẩm, giỏ hàng và bạn có thể tra cứu phí vận chuyển.
Để tiếp tục khám phá Angular:
Bạn có thể vui lòng tắt trình chặn quảng cáo ❤️ để hỗ trợ chúng tôi duy trì hoạt động của trang web.
Trong hướng dẫn này, chúng ta sẽ tìm hiểu về trình khởi động bootstrap và cách Angular hoạt động bên trong và khởi động ứng dụng của chúng ta.
Trong hướng dẫn này, chúng tôi sẽ chỉ cho bạn cách sử dụng Angular CLI để tạo một dự án mới trong Angular.
Trong hướng dẫn này, bạn sẽ tìm hiểu về không dan làm việc và cấu trúc file dự án ứng dụng, dự án thư viện của Angular.
Trong bài viết này, bạn sẽ tìm hiểu vì sao Angular lại tách riêng component và service, cách sử dụng dependency injection để khởi tạo instance của service.