我有一个购物商店应用程序,可以在其中管理产品状态和购物车状态。
在加载产品页面时,我从服务器获取了所有产品,并在redux开发工具中看到了它们。 将商品添加到购物车后,购物车的状态就会更新,但是该状态下所有产品都丢失了,在页面上也看不到它们。
在将商品添加到购物车之前: how the state looks
将商品添加到购物车后: the state
如何在不删除商品状态的情况下将商品添加到购物车,以免商品为空?
app.state:
import { CartState } from './cart/cart.state';
import ProductState from './product/product.state';
export interface AppState {
product: ProductState;
cart: CartState;
}
app.reducers
import { cartReducer } from './cart/cart.reducers';
import { productReducer } from './product/product.reducers';
export const appReducers = {
product: productReducer,
cart: cartReducer
};
购物动作
import { Action } from '@ngrx/store';
import { CartProductModel } from '../../models/cart/cart.model';
export const ADD_TO_CART = '[CART] ADD';
export const UPDATE_CART = '[CART] UPDATE CART';
export const REMOVE_FROM_CART = '[CART] REMOVE';
export const CLEAR_CART = '[CART] CLEAR';
export class AddToCart implements Action {
readonly type: string = ADD_TO_CART;
constructor(public payload: CartProductModel) {}
}
export class UpdateCart implements Action {
readonly type: string = UPDATE_CART;
constructor(public id: string, public quantity: number) {}
}
export class RemoveFromCart implements Action {
readonly type: string = REMOVE_FROM_CART;
constructor(public id: string) {}
}
export class ClearCart implements Action {
readonly type: string = CLEAR_CART;
}
cart.reducers
import { CartState } from './cart.state';
import { AppState } from '../app.state';
import {
ADD_TO_CART,
UPDATE_CART,
REMOVE_FROM_CART,
CLEAR_CART
} from './cart.actions';
import { CartProductModel } from '../../models/cart/cart.model';
const initialState: CartState = {
products: []
};
function addToCart(state: CartState, product: CartProductModel) {
if (state.products.find(p => p._id === product._id)) {
const newProducts = state.products.slice();
const cartProduct = newProducts.find(p => p._id === product._id);
cartProduct.quantity = +1;
return {
...state,
products: newProducts
};
}
return {
...state,
products: [...state.products, product]
};
}
function updateCart(state: CartState, id: string, quantity: number) {
// debugger
const newProducts = state.products.slice();
const cartProduct = newProducts.find(p => p._id === id);
cartProduct.quantity = quantity;
return {
...state,
products: newProducts
};
}
function removeFromCart(state: CartState, id: string) {
return {
...state,
products: [...state.products.filter(p => p._id !== id)]
};
}
function clearCart(state) {
return {
...state,
products: []
};
}
export function cartReducer(state: CartState = initialState, action) {
switch (action.type) {
case ADD_TO_CART:
return addToCart(state, action.payload);
case UPDATE_CART:
return updateCart(state, action.id, action.quantity);
case REMOVE_FROM_CART:
return removeFromCart(state, action.id);
case CLEAR_CART:
return clearCart(state);
default:
return state;
}
}
购物车状态
import { CartProductModel } from '../../models/cart/cart.model';
export interface CartState {
readonly products: CartProductModel[];
}
product.actions
import { Action } from '@ngrx/store';
import ProductModel from '../../models/product/product.model';
export const GET_ALL_PRODUCTS = '[PRODUCT] GET ALL';
export const CREATE_PRODUCT = '[PRODUCT] CREATE';
export const EDIT_PRODUCT = '[PRODUCT] EDIT';
export class GetAllProducts implements Action {
type: string = GET_ALL_PRODUCTS;
constructor(public payload: ProductModel[]) {}
}
export class CreateProduct implements Action {
type: string = CREATE_PRODUCT;
constructor(public payload) {}
}
export class EditProduct implements Action {
type: string = EDIT_PRODUCT;
constructor(public payload) {}
}
export type Types = GetAllProducts | CreateProduct | EditProduct;
product.reducers
import ProductState from './product.state';
import * as ProductActions from './product.actions';
const initialState: ProductState = {
all: []
};
function getAllProducts(state, action) {
return {
...state,
all: action
};
}
function createProduct(state, action) {
return {
...state,
all: [...state.all, action]
};
}
function editProduct(state, action) {
return {
...state,
all: [...state.all.filter(p => p._id !== action._id), action]
};
}
export function productReducer(
state: ProductState = initialState,
action: ProductActions.Types
) {
switch (action.type) {
case ProductActions.GET_ALL_PRODUCTS:
return getAllProducts(state, action.payload);
case ProductActions.CREATE_PRODUCT:
return createProduct(state, action.payload);
case ProductActions.EDIT_PRODUCT:
return editProduct(state, action.payload);
default:
return initialState;
}
}
product.state
import ProductModel from '../../models/product/product.model';
export default interface ProductState {
all: ProductModel[];
}
product-list.component
import { Component, OnInit, Output, DoCheck } from '@angular/core';
import { NgxSpinnerService } from 'ngx-spinner';
import { ProductService } from 'src/app/core/services/product.service';
import { Store } from '@ngrx/store';
import { AppState } from 'src/app/core/store/app.state';
import { animations } from './product-list-animation';
import { Subscription } from 'rxjs';
import ProductModel from 'src/app/core/models/product/product.model';
@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html',
styleUrls: ['./product-list.component.scss'],
animations: animations
})
export class ProductListComponent implements OnInit {
@Output()
products: ProductModel[];
subscribe$: Subscription[] = [];
protected pageSize: number = 6;
currentPage: number = 1;
constructor(
private spinner: NgxSpinnerService,
private productService: ProductService,
private store: Store<AppState>
) {}
ngOnInit() {
this.spinner.show();
this.productService.getAllProducts();
this.subscribe$.push(
this.store
.select<ProductModel[]>(state => state.product.all)
.subscribe(products => {
this.products = products;
this.spinner.hide();
})
);
}
changePage(page) {
this.currentPage = page;
}
ngOnDestroy(): void {
this.subscribe$.forEach(sub => sub.unsubscribe());
}
}
card.component
import { Component, OnInit, Input } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from 'src/app/core/services/auth.service';
import { Product } from 'src/app/models/product.model';
import { CartProductModel } from 'src/app/core/models/cart/cart.model';
import { Store } from '@ngrx/store';
import { AppState } from 'src/app/core/store/app.state';
import { AddToCart } from 'src/app/core/store/cart/cart.actions';
@Component({
selector: 'app-card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.scss']
})
export class CardComponent implements OnInit {
@Input() product: Product;
isAdmin: boolean = false;
isInCart: boolean;
route: Router;
constructor(
private authService: AuthService,
private router: Router,
private store: Store<AppState>
) {}
ngDoCheck() {
this.isAdmin = this.authService.getIsAdmin();
}
addToCart() {
if (!this.authService.isAuth()) {
this.router.navigate(['/']);
return;
}
const productToAdd = new CartProductModel(
this.product._id,
this.product.name,
this.product.image,
this.product.price,
1
);
console.log(productToAdd);
this.store.dispatch(new AddToCart(productToAdd));
}
ngOnInit() {}
}
答案 0 :(得分:0)
问题在于您的productReducer
函数中default
中的switch case
返回initialState
而不是返回state
。