NX + NGRX TypeError: entities is not iterable. Why?

NX + NGRX TypeError: entities is not iterable. Why?

我过去使用过 Ngrx,没有遇到任何问题。现在我第一次尝试使用实体,但它根本不起作用。

我在 NX 工作区中有一个 Angular9+ 应用程序调用来自服务的一些模拟数据。

谁能告诉我怎么了?我想不明白。 (这个很长post)

动作文件:

....
export const loadSheetData = createAction('[SheetData] Load SheetData');

export const loadSheetDataSuccess = createAction(
  '[SheetData] Load SheetData Success',
  props<{ sheetData: SheetDataEntity[] }>()
);
....

效果文件

....
@Injectable()
export class SheetDataEffects {
  loadSheetData$ = createEffect(() =>
    this.actions$.pipe(
      ofType(SheetDataActions.loadSheetData),
      fetch({
        run: (action) => {
          return this.bottomSheetSvc.getSheetData().pipe(
            tap((obj) => 
            catchError(error => of(new Error('Effect failed') ) ),
            map((data) => SheetDataActions.loadSheetDataSuccess({ sheetData: data}) ) );

        onError: (action, error) => {
          return SheetDataActions.loadSheetDataFailure({ error });
        },
      })
    )
  );
....

模型文件

export interface SheetDataEntity {
  id: string | number; // Primary ID
  info: string;
  link: string;
  icon?: string; 
  isDisabled?: boolean;
}

减速器文件

export const SHEETDATA_FEATURE_KEY = 'sheetData';

export interface State extends EntityState<SheetDataEntity> {
  selectedId?: string | number; // which SheetData record has been selected
  loaded: boolean; // has the SheetData list been loaded
  error?: string | null; // last none error (if any)
}

export interface SheetDataPartialState {
  readonly [SHEETDATA_FEATURE_KEY]: State;
}

export const sheetDataAdapter: EntityAdapter<SheetDataEntity> = createEntityAdapter<
  SheetDataEntity
>();

export const initialState: State = sheetDataAdapter.getInitialState({
  // set initial required properties
  entities: {
    0: {}
  },
  loaded: false,
});

const sheetDataReducer = createReducer(
  initialState,
  on(SheetDataActions.loadSheetData, (state) => ({
    ...state,
    loaded: false,
    error: null,
  })),
  on(SheetDataActions.loadSheetDataSuccess, (state, { sheetData }) => 
  {
    console.log('TEMP1:', state, sheetData);
    let temp = sheetDataAdapter.setAll(sheetData, { ...state, loaded: true })
    console.log('TEMP2:', temp);
    return temp;
  }
    
  ),
  on(SheetDataActions.loadSheetDataFailure, (state, { error }) => ({
    ...state,
    error,
  }))
);

export function reducer(state: State | undefined, action: Action) {
  console.log('SHEET REDUCER::', state, action);
  return sheetDataReducer(state, action);
}

选择器文件

....
export const getAllSheetData = createSelector(
  getSheetDataState,
  (state: State) => selectAll(state)
);
....

服务数据

dummyData: any = {
    ids: [5, 4, 3, 2, 1],
    entities: {
      1: {
        id: 1,
        info: 'test info 1',
        link: '/test1',
        icon: 'test icon 1', 
        isDisabled: false
      },
      2: {
        id: 2,
        info: 'test info 2',
        link: '/test2',
        icon: 'test icon 2', 
        isDisabled: false
      },
      3: {
        id: 3,
        info: 'test info 3',
        link: '/test3',
        icon: 'test icon 3', 
        isDisabled: false
      },
      4: {
        id: 4,
        info: 'test info 4',
        link: '/test4',
        icon: 'test icon 4', 
        isDisabled: false
      },
      5: {
        id: 5,
        info: 'test info 5',
        link: '/test5',
        icon: 'test icon 5', 
        isDisabled: false
      }
    }

  };

组件文件

sheetData$: Observable<SheetDataEntity[]>;

constructor(
    private store: Store<State>,
    ) {

      this.sheetData$ = this.store.pipe( select( selectors.getAllSheetData ) );
    }

  ngOnInit(): void {
    this.store.dispatch( actions.loadSheetData() );
  }

模板文件

<sheet-item 
        *ngFor="let item of (sheetData$ | async)" 
        [item]="item" 
        (onUpdateSelectedLink)="updateSelectedLink($emit)">
    </sheet-item>

耶!终于成功了。是一个愚蠢的错误!我将服务模拟数据修改为一个普通的项目数组。然后将其传递到“成功操作”中。尝试学习多个使用不同 Angular 版本和代码风格的教程时感到困惑。 感谢@derekkite / @RoboZoom(在 Gitter 中),你让我走上了正确的道路。 :)

run: (action) => {
          return this.bottomSheetSvc.getSheetData().pipe(
            tap((obj) => console.log('Effect: switch:', obj)),
            catchError(error => of(new Error('Effect failed') ) ),
            map((dataObj) => SheetDataActions.loadSheetDataSuccess({ sheetData: dataObj.data }) ) );
        },