首页 > 解决方案 > Ngrx:如何防止元素数组中状态更新后的数据丢失?

问题描述

我的 Angular 应用程序显示了一个列表,Item其中每个Item(组件)都有自己的状态,由以下属性组成:

{
    name: 'item name',
    status: 'OK'
}

我使用 ngrx 存储来维护每个组件的更新状态(OK 状态通过 Effect 来自后端服务,因此我异步检索数据以放入存储中)。

Angular 轮询后端服务,如果第 n 个项目的状态字段不正常,则 UI 必须使用不同的颜色。

后端服务返回上面显示类型的项目数组,并将其放入list下面。

所以,这里是州代表:

export interface State {
    list: Item[]
}

现在我想在事件的列表的每个项目中再存储一个信息:open不依赖于后端的属性。单击按钮时通过 UI 设置它。

所以我会在某个时候有这样的状态:

[{
    name: 'item 1',
    status: 'OK',
    open: true
},
{
    name: 'item 2',
    status: 'OK',
    open: false
},
{
    name: 'item 3',
    status: 'OK'
}
...
{
    name: 'item n',
    status: null
}]

open属性由 UI 事件设置。其他属性来自后端(通过数组)。

我的问题是,每次我调度从后端服务中提取数据的操作时,所有元素都会被覆盖(我清楚地理解为什么),我有这个:

[{
    name: 'item 1',
    status: 'OK'
},
{
    name: 'item 2',
    status: 'OK'
},
{
    name: 'item 3',
    status: 'OK'
}
...
{
    name: 'item n',
    status: null
}]

解决这个问题的最佳方法是什么?我认为它可以很容易地解决到减速器中,但我仍然无法弄清楚如何。

我尝试过了:

但我认为在这两种情况下我都会遇到同步问题

case ItemsActions.STORE_ITEM_LIST:
    return {
    ...state,
    list: action.payload
}

为此(更新指定每个字段的每个项目):

case ItemsActions.STORE_ITEM_LIST:
return {
    ...state,
    list: action.payload.map((item, index) => {
        action.payload[index].name === item.name ? {
            ...item,
            name: item.name,
            status: item.status
        } : item
    })
}

标签: stateangular7ngrx

解决方案


理论上,您必须映射有效负载并将当前状态值与传入值“连接”。

这转化为以下实现:

case ItemsActions.STORE_ITEM_LIST:
return {
    ...state,
    list: action.payload.map((item) => ({
            ...state.list.find(item2 => item2.name === item.name) || {}, // if the item isn't found just create an empty object
            name: item.name,
            status: item.status

    }))
}

为了使这些更新更容易,您可以查看:


推荐阅读