Angular 2 NGRX:谁初始化了路由器?

时间:2017-04-10 21:56:07

标签: angular ngrx

我按照NGRX example app的示例构建了路由器,确切地说是布局路由器。新代码如下所示:

AppComponent:

import * as fromRoot from '../../reducers';
import * as uiActions from '../../actions/ui-actions';

@Component({
  selector: 'app-root',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
  <div #wrapper>
    <div>
      <app-header (toggleFullscreen$)="toggleFullscreen()"></app-header>
    </div>
  </div>
 `
})
export class AppComponent {
  @ViewChild('wrapper') wrapper: ElementRef;
  isFullScreen$: Observable<boolean>;

  constructor(private store: Store<fromRoot.State>){
    this.isFullScreen$ = this.store.select(fromRoot.getFullscreenMode);
  }

  isFullscreenAvailable(): boolean { ...
  }

  toggleFullscreen() {
    if (!this.isFullScreen$.last){
      if (this.isFullscreenAvailable) {
        this.store.dispatch(new uiActions.EnableFullscreen());
      }
    } else {
      this.store.dispatch(new uiActions.DisableFullscreen());
    }
  }

  ngOnInit(){
    this.isFullScreen$.subscribe((isFullscreen: boolean) => {...}
  }

UiReducer:

import * as uiActions from "../actions/ui-actions";

export interface State {
  fullscreen: boolean;
}

const INITIAL_UI_STATE: State = {
  fullscreen: false
};

export function reducer(state: State = INITIAL_UI_STATE, action: uiActions.Actions): State {
  switch (action.type) {
    case uiActions.ActionTypes.ENABLE_FULLSCREEN: {
      return {
        fullscreen:true
      }
    }
    case uiActions.ActionTypes.DISABLE_FULLSCREEN: {
      return {
        fullscreen:false
      }
    }
    default: {
      console.log("default state: "+ JSON.stringify(state));
      return state;
    }
  }
}

export const getFullscreenMode = (state: State) => {
  console.log("state from reducer method : " + state)
  return state.fullscreen;
}

路由器目录的index.ts内部:

export const getUiState = (state: State) => state.uiState;
export const getFullscreenMode = createSelector(getUiState, fromUi.getFullscreenMode);

但是当我启动应用程序时出现错误,我不知道如何追溯它们。控制台说:

ui-reducer.ts:24 default state: {"fullscreen":false}
ui-reducer.ts:24 default state: {"fullscreen":false}
ui-reducer.ts:31 state from reducer method : undefined
TypeError: Cannot read property 'fullscreen' of undefined ...
state from reducer method : undefined
zone.js:569 Unhandled Promise rejection: Cannot read property 'fullscreen' of undefined
Error: Uncaught (in promise): TypeError: Cannot read property 'fullscreen' of undefined

正如我所说,我不知道如何调试它。当路由器的流初始化时,最初调用路由器的是什么?有一些背景过程吗?它似乎尝试在初始化之前访问存储变量。为什么这个代码在示例应用程序中看起来完全相同时对我不起作用?

1 个答案:

答案 0 :(得分:0)

对于遇到此问题的其他人,问题不在我发布的代码中,但在

中有不同的变量名称
export interface State {
  layoutState: fromLayout.State;
}

const reducers = {
  layoutReducer: fromLayout.reducer,
};

在这种情况下,layoutState和layoutReducer必须被调用相同,因为选择器引用reducer,而编译器将状态显示为引用对象,导致很多混淆