NGRX Store.select没有正确投影状态

时间:2018-04-20 03:12:32

标签: angular typescript redux ngrx

当我这样做时

valueToDisplay$ =store.select('model','sub-model')

valueToDisplay $的值最终是' model'的值。我已经尝试了很多东西来正确地预测状态,但我显然错过了一些关于NGRX商店如何引导的重要事项。

AppComponent
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';


import { AppComponent } from './app.component';
import { SetViewComponent } from './set-view/set-view.component';
import { MoveInputComponent } from './move-input/move-input.component';
import { MoveViewComponent } from './move-view/move-view.component';
import { movementsReducer } from './shared/store/set.store';



@NgModule({
  declarations: [
    AppComponent,
    SetViewComponent,
    MoveInputComponent,
    MoveViewComponent,
  ],
  imports: [
    BrowserModule,
    StoreModule.forRoot({movementsReducer:movementsReducer})
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

减速机: 目前过度嵌套的状态对象,但它并没有改变我迄今为止的基本方法。

import { DanceSet, Movement } from "../model/model";
import { Action, ActionReducerMap } from "@ngrx/store";
import { Injectable } from "@angular/core";
// STATE
export interface MovementState {
    movementsReducer:{
        movements?:Movement[],
        lastId?:number
    },
}
export const INITIAL_STATE:MovementState = {
    movementsReducer:{movements:[],lastId:0},

}
// ACTION NAMES
export enum MovementActionTypes  {
    ADD_MOVEMENT='[MOVEMENT] ADD_MOVEMENT',
    REMOVE_MOVEMENT='[MOVEMENT] REMOVE_MOVEMENT'
}

// ACTION CLASSES
export class AddMovementAction implements Action {
    readonly type = MovementActionTypes.ADD_MOVEMENT;
    constructor(public payload: Movement){};
}
export class RemoveMovementAction implements Action{
    readonly type =  MovementActionTypes.REMOVE_MOVEMENT;
    constructor(public payload:number){};
}

// Action TYPES
export type MovementActions
    = AddMovementAction | RemoveMovementAction

//Util
export function filterOutMovement(movements:Movement[], id:number):Movement[]{
    return movements.filter(item =>item.id !== id);
}

// Dance Set Reducer
export function movementsReducer(state: MovementState = INITIAL_STATE, action:any ): MovementState{
    switch(action.type){
        case MovementActionTypes.ADD_MOVEMENT:
            return {
                ...state,
                movementsReducer:{movements: [...state.movementsReducer.movements, action.payload], lastId:state.movementsReducer.lastId+1},
            }
        case MovementActionTypes.REMOVE_MOVEMENT:
            return{
             ...state,
                movementsReducer:{movements:filterOutMovement(state.movementsReducer.movements,action.payload), lastId:state.movementsReducer.lastId}
            }   
    default:
        return state;
    }
}

当前视图组件: 在我的模板中,我试图展示当前'运动$'但是,当我实际记录对象是什么时,我发现这不是状态的一部分,而是整个状态本身。

import { Component, OnInit } from '@angular/core';
import { MovementState, MovementActionTypes, AddMovementAction } from '../shared/store/set.store';
import { Store, select } from '@ngrx/store';
import { Movement } from '../shared/model/model';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'app-set-view',
  templateUrl: './set-view.component.html',
  styleUrls: ['./set-view.component.css']
})
export class SetViewComponent implements OnInit {
  public movements$:Array<Movement>;
  subscription;

  constructor(private store:Store<MovementState>) { 
    this.subscription = this.store.select('movementsReducer', 'movements').subscribe(value => this.movements$=value);
  }

  ngOnInit() {
  }

  addMove(name, id){
    let move = new Movement('Test',1);
    this.store.dispatch(new AddMovementAction(move));
  }

}

1 个答案:

答案 0 :(得分:0)

为我想要的小片段创建一个特征选择器和一个选择器似乎解决了它。从API码头看起来我似乎不应该这样做但是唉,这里是IT。

import { createFeatureSelector, createSelector, ActionReducerMap, ActionReducer, MetaReducer } from "@ngrx/store";
import { MovementState, movementsReducer } from "./set.store";
import { environment } from "../../../environments/environment";

export interface AppState{
    movementState:MovementState;
}
export const getMovementState = createFeatureSelector<MovementState>('movementState');

export const getMovements = createSelector(
    getMovementState,
    (state:MovementState) => state.movementReducer.movements
)
export const getLastId = createSelector(
    getMovementState,
    (state:MovementState) => state.movementReducer.lastId
)

export const reducers: ActionReducerMap<AppState>={
    movementState:movementsReducer
}

export function logger(reducer: ActionReducer<AppState>): ActionReducer<AppState> {
    return function(state: AppState, action: any): AppState {
      console.log('state', state);
      console.log('action', action);
      return reducer(state, action);
    };
  } 


export const metaReducers: MetaReducer<AppState>[] = !environment.production
? [logger]
: [];