Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular NGRX Store.select未正确投影状态_Angular_Typescript_Redux_Ngrx - Fatal编程技术网

Angular NGRX Store.select未正确投影状态

Angular NGRX Store.select未正确投影状态,angular,typescript,redux,ngrx,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'; i

当我这样做的时候

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;
    }
}
当前视图组件: 在我的模板中,我试图显示当前的“movements$”是什么,但当我实际记录对象是什么时,我发现它不是状态的一部分,而是整个状态本身

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));
  }

}

创建一个特性选择器和一个我想要的小部分状态选择器似乎可以解决这个问题。从API接口来看,似乎我“不应该”需要这样做,但唉,它就在这里

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]
: [];