2017-04-10 126 views
0

我按照NGRX example app的例子構建了一個路由器,佈局路由器是精確的。新代碼如下所示:Angular 2 NGRX:誰初始化路由器?

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 

正如我所說,我不知道如何調試這一點。什麼時候調用路由器,當它的流尚未初始化?是否有一些後臺進程?它似乎試圖在初始化之前訪問商店變量。爲什麼在示例應用程序中看起來完全相同時,此代碼對我無效?

回答

0

爲了其他任何人遇到這個問題,這個問題並沒有在我張貼,但在這種情況下

export interface State { 
    layoutState: fromLayout.State; 
} 

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

有因爲選擇是指layoutState和layoutReducer必須調用同一個不同的變量名稱代碼減速器,而編譯器顯示狀態爲引用對象,引起很多混淆