Angular 6 ngrx-如何与ShopModule.forRoot一起使用多个reducer

时间:2018-12-29 01:57:18

标签: redux angular6 ngrx

Original post located at this dropbox link

感谢@rijin重写代码: reducers / index2.ts:

import { ActionReducerMap } from "@ngrx/store";
import { userReducer, UserState } from "./user2.reducer";
import { cartReducer, CartState } from "./cart2.reducer";

interface AppState {
  user: UserState;
  cart: CartState;
}

export const reducers2: ActionReducerMap<AppState> = {
  user: userReducer,
  cart: cartReducer
};

用户:userReducer上的编译错误:

Type '(appUserState: UserState, action: any) => User' is not assignable to type 'ActionReducer<UserState, Action>'.
Property 'user' is missing in type 'User' but required in type 'UserState'.

/reducers/user.ts:

 export class User {
  uName: string;
  isAdmin: boolean;
  ts: string;
  loggedIn: boolean;
  constructor(data: any) {
    Object.assign(this, data);
  }
}

/reducers/cart.ts:

export class Cart {
  counter: number;
  constructor(data: any) {
    Object.assign(this, data);
  }
}

/reducer/user2.reducer.ts:

import * as UserActions from "../actions/user.actions";
import { User } from "./user";

function mTstamp() {
  let d = new Date();
  let mMonth;
  if (d.getMonth() < 10) {
    mMonth = "0" + d.getMonth();
  } else {
    mMonth = d.getMonth();
  }
  let mDate;
  if (d.getDate() < 10) {
    mDate = "0" + d.getDate();
  } else {
    mDate = d.getDate();
  }
  let mHours;
  if (d.getHours() < 10) {
    mHours = "0" + d.getHours();
  } else {
    mHours = d.getHours();
  }
  let mMins;
  if (d.getMinutes() < 10) {
    mMins = "0" + d.getMinutes();
  } else {
    mMins = d.getMinutes();
  }
  let mSecs;
  if (d.getSeconds() < 10) {
    mSecs = "0" + d.getSeconds();
  } else {
    mSecs = d.getSeconds();
  }
  let mTimeStamp =
    d.getFullYear() +
    "-" +
    mMonth +
    "-" +
    mDate +
    " " +
    mHours +
    ":" +
    mMins +
    ":" +
    mSecs;
  console.log("mTimeStamp: ", mTimeStamp);
  return mTimeStamp;
}

export interface UserState {
  user: User;
}

const initialLoginState: UserState = {
  user: new User({
    uName: "Guest",
    isAdmin: false,
    ts: mTstamp(),
    loggedIn: false
  })
};

export function userReducer(appUserState = initialLoginState, action): User {
  switch (action.type) {
    case UserActions.ACTION_LOGOUT:
      return {
        ...appUserState,
        uName: "Guest",
        isAdmin: false,
        ts: mTstamp(),
        loggedIn: false
      };
    case UserActions.ACTION_LOGIN:
      return {
        ...appUserState,
        uName: action.payload,
        isAdmin: action.payload,
        ts: action.payload,
        loggedIn: action.payload
      };
  }
  return appUserState;
}

返回appUserState时出现编译错误:

Type 'UserState' is missing the following properties from type 'User': uName, isAdmin, ts, loggedIn

/reducers/cart.reducer.ts:

import * as CartActions from "../actions/cart.actions";
import { Cart } from "./cart";

export interface CartState {
  cart: Cart;
}

const initialCartState: CartState = {
  cart: new Cart({
    counter: 0
  })
};

export function cartReducer(cartState = initialCartState, action): CartState {
  switch (action.type) {
    case CartActions.ACTION_DECREMENT:
      return {
        ...cartState,
        counter: action.payload
      };
    case CartActions.ACTION_INCREMENT:
      return {
        ...cartState,
        counter: action.payload
      };
  }
  return cartState;
}

计数器的编译错误:action.payload:

Type '{ counter: any; cart: Cart; }' is not assignable to type 'CartState'.
Object literal may only specify known properties, and 'counter' does not exist in type 'CartState'.

对不起,但是我可以克服这些错误。请让我知道如何解决这些问题

1 个答案:

答案 0 :(得分:1)

合并并为根使用一个ActionReducerMap。

每个状态都应映射到相应的reducer。

  

请参阅stackblitz网址:https://stackblitz.com/edit/angular-ngrx-tryout

// cart.reducer

export function cartReducer(cartState = initialCartState, action): CartState {
  console.log('prev state: ', cartState);
  switch (action.type) {
    case CartActionTypes.ACTION_DECREMENT:
      return {
        ...cartState, // no other properties, can be removed
        cart: new Cart({ counter: action.payload.counter })
      };
    case CartActionTypes.ACTION_INCREMENT:
      return {
        ...cartState, // no other properties, can be removed
        cart: new Cart({ counter: action.payload.counter })
      };
  }
  return cartState;
}

export const selectCartState = (state) => state.cartState;
export const selectCart = createSelector(selectCartState, (state) => state.cart);

// store / index.ts

import { ActionReducerMap } from "@ngrx/store";
import { userReducer, UserState } from "./user.reducer";
import { cartReducer, CartState } from "./cart.reducer";

interface AppState {
  userState: UserState;
  cartState: CartState;
}

export const reducers: ActionReducerMap<AppState> = {
  userState: userReducer,
  cartState: cartReducer
};

//并导入

StoreModule.forRoot(reducers),