首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >角:使用Immutable.js更新ngrx存储状态的嵌套数组。

角:使用Immutable.js更新ngrx存储状态的嵌套数组。
EN

Stack Overflow用户
提问于 2018-01-09 18:43:36
回答 1查看 1K关注 0票数 0

我正在试图上传我的目标之一的状态,但目前没有成功。

每次用户单击Add To Cart时,我都想用一个新项目更新购物车记录。

这是我的ngrx-store州:

代码语言:javascript
复制
export interface UserState extends Map<string, any> {
    user: User;
    cart: Cart;
    addedToCart: boolean;
}

/* Initial state of any user */
export const UserStateRecord = Record( {
    user: Map( {} ),
    cart: Map( {} ),
    addedToCart: false
} );

手推车模型如下:

代码语言:javascript
复制
export class Cart {
    constructor(
        public created: string,
        public totalAmount: number,
        public items: List<Item>
    ) { }
}

export class Item {
    constructor(
        public quantity: number,
        public totalAmount: number,
        public product: Product
    ) {  }
}

当用户向其购物车添加一个项时,就会分派一个ADD_TO_CART类型的操作。如果商品已经在购物车内,我需要更新数量和总价格,否则我需要添加一个新的项目到购物车。

以下是我目前所写的减速器开关箱:

代码语言:javascript
复制
case UserActions.ADD_TO_CART:
    const newItems = state.cart.items.map( item => {
        if ( item.product.id === payload.id ) {
            return Map( item ).merge( {
                'quantity': 1 + item.quantity,
                'totalAmount': item.totalAmount + ( item.totalAmount / item.quantity )
            } );
        } else {
            return item;
        }
    } );
    //CODE SHOULD BE ADDED HERE TO UPDATE THE STATE
    return state.merge( {
        addedToCart: true
    } ) as UserState;

Q1newItems包含新的一组项,但我不知道如何将它们合并到状态。你知道怎么做吗?

Q2:另外,如果购物车中还没有新条目,我如何添加它呢?

Q3:为了使用合并,我必须将项目转换为地图(Map ( item )),但是最好已经为购物车中的每个项目提供了一个地图。有人知道怎么做到这一点吗?

提前谢谢你

EN

回答 1

Stack Overflow用户

发布于 2018-01-10 00:37:38

上面的例子有点混乱,因为您说您的模型是正常的类,但是在您的状态下,它们显示为Map的.

代码语言:javascript
复制
export const UserStateRecord = Record( {
    user: Map( {} ), // this disagrees with the User class!
    cart: Map( {} ), // this disagrees with the Cart class!
    addedToCart: false
} );

假设您真正的意思是用户和购物车类也是RecordUserState,因此继承了Map方法.

像这样使用updateupdateIn应该可以为减速器开关箱.

代码语言:javascript
复制
return state.merge({
  // immutably update items in cart, providing default empty items List if not existing
  cart: state.cart.updateIn(
    ['items'], // path
    List<Item>(), // default empty item list iof not existing
    (items: List<Item>) => items.update( // updater for existing items
      // find index of exsisting item
      state.cart.items.findIndex(item => item.product.id === payload.id),
      // the new item to add if index not found, assuming this is in payload as not shown above 
      payload.item, 
      // updater for existing item, lets stay immutable and just create a new Item instance with updated properties
      existing => new Item(existing.quantity + 1, 
                          existing.totalAmount + (existing.totalAmount / existing.quantity), // not sure what this is calculating but you had it in original
                          existing.product)                 
    )
  ),
  addedToCart: true
})

然而,在我看来,您对记录的定义似乎也不同,为了编译上面的记录并强键入记录,我没有使用class Cart extends Map<string, any>,而是使用了以下技巧:扩展包含字段默认值的实例化Record,并显式声明访问器的属性类型.

代码语言:javascript
复制
export class Cart extends Record({created: undefined, totalAmount: 0, items: List<Item>()}) {
  created: string
  totalAmount: number
  items: List<Item>
}

// omitting `user` as has no bearing on this question
export class UserState extends Record({cart: undefined, addedToCart: false}) {
  cart: Cart
  addedToCart: boolean
}

export const state = new UserState({cart: new Cart()})
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48174748

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档