Last active
June 29, 2018 16:33
-
-
Save perjerz/ff6c98aabce25c192cc462d84c74ccb5 to your computer and use it in GitHub Desktop.
NgRx Blog
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Item } from './cart.interfaces'; | |
export const EXAMPLE_ACTION = 'EXAMPLE_ACTION'; | |
export const ADD_ITEM_TO_CART = 'ADD_ITEM_TO_CART'; | |
export const LIST_ITEMS = 'LIST_ITEMS'; | |
export const ITEMS_LISTED = 'ITEMS_LISTED'; | |
export const UPDATE_ITEM_AMOUNT = 'UPDATE_ITEMS_AMOUNT'; | |
export const ITEM_AMOUNT_UPDATED = 'ITEM_AMOUNT_UPDATED'; | |
export const REMOVE_ITEM = 'REMOVE_ITEM'; | |
export class ExampleAction { | |
// ประกาศ attribute type สำหรับระบุว่าเป็น Action อะไร ใน Reducer | |
readonly type = EXAMPLE_ACTION; | |
// payload คือของที่จะส่งเข้าไปกับ Action ซึ่งก็คือ Item นั้นและจำนวน จะมัดรวมเป็น Object ก้อนเดียวก็ได้ แต่ผู้เขียนชอบแยกกัน | |
} | |
// Action ดึงข้อมูล Item ทั้งหมดจาก API (Side Effect) | |
export class ListItems { | |
readonly type = LIST_ITEMS; | |
constructor() {} | |
} | |
// Action รับข้อมูลที่ได้จาก API (Update State) | |
export class ItemsListed { | |
readonly type = ITEMS_LISTED; | |
constructor(public items: Item[]) {} | |
} | |
// Action User เพิ่มสินค้าเข้ารถเข็นผ่าน API (Side Effect) | |
export class AddItemToCart { | |
readonly type = ADD_ITEM_TO_CART; | |
constructor(public item: Item, public amount: number) {} | |
} | |
// Action User แก้ไขจำนวนสินค้าในรถเข็น ยิงไปที่ API (Side Effect) | |
export class UpdateItemAmount { | |
readonly type = UPDATE_ITEM_AMOUNT; | |
constructor(public id: string, public amount: number) {} | |
} | |
// Action อัพเดท State ของ Item Amount ใน App (Reducer) | |
export class ItemAmountUpdated { | |
readonly type = ITEM_AMOUNT_UPDATED; | |
constructor(public id: string, public amount: number) {} | |
} | |
// Action User เอาสินค้าออกจากรถเข็น ยิงไปที่ API (Side Effect) | |
export class RemoveItems { | |
readonly type = REMOVE_ITEM; | |
constructor(public id: string) {} | |
} | |
// Action User อัพเดท State เอา Item ออกด้วย id ใน App (Reducer) | |
export class ItemsRemoved { | |
readonly type = REMOVE_ITEM; | |
constructor(public id: string) {} | |
} | |
// Action User จ่ายเงิน ยิง Api หลังบ้านตัดเงิน | |
export class CheckOut { | |
constructor() {} | |
} | |
export type CartAction = | |
| ExampleAction | |
| AddItemToCart | |
| ListItems | |
| ItemsListed | |
| UpdateItemAmount | |
| ItemAmountUpdated | |
| RemoveItems | |
| ItemsRemoved | |
| CheckOut; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { CartState } from './cart.interfaces'; | |
import { ADD_ITEM_TO_CART, LIST_ITEMS, ItemToCartAdded, AddItemToCart } from './cart.actions'; | |
@Injectable() | |
export class CartEffects { | |
// Decorator ระบุว่าคือ Effect และสามารถตั้งค่าว่าาจะ Dispatch Action กลับไปหรือไม่ | |
@Effect(/*{dispatch: false}*/) // สามารถตั้งได้ว่าไม่ dispatch action | |
addItemToCart$ = this.actions$.pipe( | |
// สนใจแค่สายข้อมูล Action ของ Add Item To Cart | |
.ofType(ADD_ITEM_TO_CART), | |
switchMap((action: AddItemToCart) => | |
this.http.post('/item', {id: action.id, amount: action.amount}) | |
.pipe( | |
map(item => new ItemToCartAdded(item.id, item.amount)), // dispatch Action เพื่ออัพเดท item id, amount ไปที่ reducer | |
catchBackendError(err => console.error(err)) | |
) | |
) | |
); | |
@Effect() | |
listItems$ = this.actions$.pipe( | |
// สนใจแค่สายข้อมูล Action ของ List Items | |
.ofType(LIST_ITEMS), | |
switchMap(() => this.http.get('/items').pipe( | |
map(item => new ItemsListed(item)), // dispatch Action เพื่ออัพเดท displayItems ทั้งหมด | |
catchBackendError(err => console.error(err)) | |
) | |
) | |
); | |
constructor( | |
private http: HttpClient, | |
private store: Store<CartState>, | |
private actions$: Actions | |
) {} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export interface Item { | |
id: string; | |
name: string; | |
type: string; | |
price: string; | |
description: string; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Cart } from './cart.interfaces'; | |
import { | |
CartAction, | |
ITEM_TO_CART_ADDED, | |
ITEMS_LISTED, | |
ITEM_AMOUNT_UPDATED, | |
ITEMS_REMOVED | |
} from './cart.actions'; | |
import { initialState } from './cart.init'; | |
export function cartReducer(state = initialState, action: CartAction): Cart { | |
switch (action.type) { | |
case ITEM_TO_CART_ADDED: | |
case ITEM_AMOUNT_UPDATED: { | |
return { ...state, selectedItems: { ...state.selectedItems, [action.id]: action.amount } }; | |
} | |
case ITEMS_LISTED: { | |
return { ...state, displayItems: action.items }; | |
} | |
case ITEMS_REMOVED: { | |
const { [action.id]: omitItem, ...otherItems } = state.selectedItems; | |
return { ...state, selectedItems: otherItems }; | |
} | |
default: | |
return state; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment