[英]ngrx/store-angular - state not keeping some data
I have a shopping store app where I manage Product State and Cart state.我有一个购物商店应用程序,我在其中管理产品 State 和购物车 state。
On loading the products page I get all the Products from the server and see them in the redux dev tool.在加载产品页面时,我从服务器获取所有产品并在 redux 开发工具中查看它们。 Once I add an item to my cart the cart state is getting updated but all the products are missing from the state and I can't see them any more on the page.
将商品添加到购物车后,购物车 state 就会更新,但 state 中的所有产品都丢失了,我在页面上再也看不到它们了。
Before adding item to cart: how the state looks在将商品添加到购物车之前: state 的外观
after adding item to cart: the state将商品添加到购物车后: state
how can I add Items to the cart without deleting the products state so it wont be empty?如何在不删除产品 state 的情况下将商品添加到购物车,这样它就不会为空?
app.state: app.state:
import { CartState } from './cart/cart.state';
import ProductState from './product/product.state';
export interface AppState {
product: ProductState;
cart: CartState;
}
app.reducers app.reducers
import { cartReducer } from './cart/cart.reducers';
import { productReducer } from './product/product.reducers';
export const appReducers = {
product: productReducer,
cart: cartReducer
};
cart.actions购物车.actions
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;
}
}
cart.state购物车.state
import { CartProductModel } from '../../models/cart/cart.model';
export interface CartState {
readonly products: CartProductModel[];
}
product.actions 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 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产品.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() {}
}
The problem is that in your productReducer
function the default
in the switch case
returning the initialState
instead of returning the state
.问题在于,在您的
productReducer
function 中, switch case
中的default
返回initialState
而不是返回state
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.