简体   繁体   English

ngrx/store-angular - state 没有保留一些数据

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM