Angular ngrx ngrx/store Redux
▌Introduction
In the previous practice, we had successfully created an Angular app
with ngrx/store
to keep the shopping cart state in our application.
Let’s improve the application by storing the individual product’s
information in the state, and therefore we can show what a user are going to
buy from the shopping cart.
▋Source code
▋Related articles
[Angular] Redux with ngrx/store – Shopping cart sample (2)
[Angular] Redux with ngrx/effects – Shopping cart sample (3)
[Angular] Redux with ngrx/effects – Shopping cart sample (3)
▌Environment
▋Angular 5.2.0
▋@ngrx/store 5.2.0
▌Implement
▋Update state class
▋ShopCart.ts
Add
a new property, ShopItem[]
array into the ShopCart class.
import { IShopCart } from '../interface/IShopCart';
import { ShopItem } from '../class/ShopItem';
export class ShopCart implements IShopCart {
items:
ShopItem[];
cnt: number;
sum: number;
constructor() {
this.items = [];
this.cnt = 0;
this.sum = 0;
}
}
▋ShopItem.ts
Also
we should keep the id and title of the item we put in
the shopping cart.
export class ShopItem {
id: string; //Product ID
title: string; //Product
name
count: number; //Counter
price: number; //Cash
summary
public constructor(
public constructor(
fields?: {
id?: string,
title?: string,
count?: number,
price?: number
}) {
if (fields) {
Object.assign(this, fields);
} else {
this.count = 0;
this.price = 0;
}
}
}
▋Update reducer
We
should implement the following logic in actions.
1.When
pushing an item into the shopping cart,
1-1. If the item is first time being push, add it to the state.
1-2. Or update the count of the item in the state.
1-1. If the item is first time being push, add it to the state.
1-2. Or update the count of the item in the state.
2.When
pulling an item from the shopping cart,
2-1. Update the count of the item in the state.
2-2. Check if the item’s count equals zero, if yes, remove the item from the state.
2-1. Update the count of the item in the state.
2-2. Check if the item’s count equals zero, if yes, remove the item from the state.
▋shopcart.action.ts
export const PUSH = 'PUSH';
export const PULL = 'PULL';
export const CLEAR = 'CLEAR';
export function
shopcartReducer(state: ShopCart = new ShopCart(),
action: ShopcartAction) {
switch
(action.type) {
case PUSH:
return
pushToCart(state, action.payload);
case PULL:
return
pullFromCart(state, action.payload);
case CLEAR:
state.cnt = 0;
state.sum = 0;
state.items = [];
return state;
default:
return state;
}
}
function pushToCart(shopcart: ShopCart, payload: ShopItem):ShopCart {
shopcart.cnt += 1;
shopcart.sum += payload.price * 1;
updateItems(shopcart, payload);
return shopcart;
}
function pullFromCart(shopcart: ShopCart, payload: ShopItem): ShopCart {
shopcart.cnt -= 1;
shopcart.sum -= payload.price * 1;
updateItems(shopcart, payload);
return shopcart;
}
function updateItems(shopcart: ShopCart, payload: ShopItem) {
let targetItem = shopcart.items.find(item => item.id === payload.id);
if (targetItem) { //Exist
if (payload.count <= 0) {
var index = shopcart.items.indexOf(targetItem);
shopcart.items.splice(index, 1);
}
else {
targetItem.count = payload.count;
}
}
else { //First time adding to shopping cart
shopcart.items.push(payload);
}
}
Okay,
it’s done. We have successfully made the state supports keeping the individual
product information.
▋Using the current
state
We
will use the current state to get the items in the shopping cart, and then
update the display value in the view.
Take
ProductBooksComponent
for example,
▋product-books.component.ts (Update)
ngOnInit() {
this.initBooks();
}
//Initialize books
private initBooks() {
this.productService.getByType(PROD_TYPE).subscribe(data => {
this.books = data;
//Use shopping cart to update data
this.shopcart$.subscribe(cart => {
this.books.forEach(item => {
if (cart.items) {
let storeItem = cart.items.find(x => x.id === item.id);
if (!storeItem) {
this.itemNumbers[item.id] = 0;
}
else {
this.itemNumbers[item.id] = storeItem.count;
}
}
});
})
})
}
▋Save the state
(Shopping cart)
Everything
is done for our shopping cart, all we have to do is send the state’s
information to backend after user clicks a save button or whatever.
(I
will skip this practice, but you can take a deep look at my source code which
integrates Firebase … :)
▋Demo
▌Reference
沒有留言:
張貼留言