本文介绍了当ngrx存储状态包含映射时,为什么无法识别对此映射的更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据他们的示例-app,我迁移到了Ngrx Store v4.1.1(+Angular5)。除了一个子存储外,一切都像以前一样运行正常。该子存储的状态包含一个已更改的映射。但对此地图的更改不知何故无法识别。

可以在以下位置找到工作柱塞:https://plnkr.co/edit/2Z77Cq?p=preview详细代码如下

我的NgModule是这样的:

import {reducers} from './reducers';

@NgModule({
   imports: [ 
     BrowserModule,
     StoreModule.forRoot(reducers) 
   ],
   declarations: [ App ],
   bootstrap: [ App ],
   providers: [Service]
})

我的减速机看起来是这样的:

import {
  ActionReducerMap,
  createSelector,
  createFeatureSelector,
} from '@ngrx/store';

import * as character from './character.reducer';

export interface State {
  character: character.State;
}

export const reducers: ActionReducerMap<State> = {
  character: character.reducer,
};

/** Character **/
export const getCharacterState = createFeatureSelector<character.State>('character');

export const getCharacter = createSelector(
  getCharacterState,
  character.getCharacter
);

SubStore Reducer包含以下代码:

import { Character, Item } from './models';
import * as character from './character';

export interface State {
  character: Character;
}

export const initialState: State = {
  character: null,
};

export function reducer(state = initialState, action:character.Actions): State {
  switch (action.type) {
    case character.INIT_CHARACTER:
      const char: Character = action.payload;
      state.character = char;
      console.log('init char', char);
      return Object.assign({}, state);

    case character.EQUIP_ITEM:
      const eqItem: Item = action.payload;
      state.character.wardrobeItemIds.set(eqItem.part, eqItem.id);
      console.log('eq ITEMMM', eqItem, state.character.wardrobeItemIds);
      return Object.assign({}, state);

    default:
      return state;
  }
}

export const getCharacter = (state: State) => state.character;

对应的操作为:

import { Action } from '@ngrx/store';
import { Character, Item } from './models';

export const INIT_CHARACTER = '[Character] Initialized Character';
export const EQUIP_ITEM = '[Character] Equipped Item';

export class InitCharacter implements Action {
  readonly type = INIT_CHARACTER;
  constructor(public payload: Character) {}
}

export class EqItem implements Action {
  readonly type = EQUIP_ITEM;
  constructor(public payload: Item) {}
}

export type Actions =
  InitCharacter |
  EqItem;

现在我在我的服务中使用新字符初始化子存储区:

import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import {Character, Item} from './models';

import * as fromRoot from './reducers.ts';
import * as CharacterAction from './character.ts';

@Injectable()
export class Service {
  character$: Observable<Character>;

  constructor(
    private store: Store<fromRoot.State>
  ) {
    // listen to the store
    this.character$ = this.store.select(fromRoot.getCharacter);

    this.character$.subscribe(
      (state: any) => console.log('char store triggered. State:', state)
    );

    // init the wardrobeItemIds Map
    const wardrobeItemIds = new Map<string, string>();
    wardrobeItemIds.set('part1', 'anyId');

    // init the character (this is just a dummy)
    let newCharacter: Character = {
      baseType: 'anyString',
      skinItemIds: [
        'string1',
        'string2'
      ],
      wardrobeItemIds: wardrobeItemIds
    }
    this.store.dispatch(new CharacterAction.InitCharacter(newCharacter));
  }

  addItem(part: string): void {
    // add rnd item of given part
    const item: EquipItem = {
      id: Math.random().toString(),
      part: part,
    }
    this.store.dispatch(new CharacterAction.EqItem(item));
  }
} 

这会导致我在同一服务内订阅

this.character$.subscribe(
  (state: any) => console.log('char store triggered. State:', state)
);

记录字符,这很好,因为它从NULL更改为Character对象。

现在,如果我调用addItem(),它调用this.store.dispatch(new CharacterAction.EqItem(item));,它应该向映射state.character.wardrobeItemIds添加一个项目。

这应该会导致Store Observable再次触发,并且订阅应该记录更改后的字符。但不知何故,什么也没发生。已检查减速器是否正确接收操作。

不确定这是我的愚蠢还是某种错误?

提前

Thx托比

推荐答案

似乎@ngrx/Entity是针对存储中更复杂的数据结构的预期解决方案。如果启用Map,则使用Map将触发新的运行时检查,因为它们既不是不可变的,也不是可序列化的。

这篇关于当ngrx存储状态包含映射时,为什么无法识别对此映射的更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 09:17