2017-09-02 15 views
0

ngRxのドキュメントからかなり巧妙な例を使用して、Angularアプリのreduxモデルを試してみます。以下のコードは動作します。すべてのアクションが起動し、ストアを正しく更新します。私はredux開発ツールと店舗のロガーでそれらを見ることができます。ngRx/store Angularテンプレートで観測可能な値が表示されない

ただし、テンプレートには何も表示されません。それは空白です。それはこのようになります状態の木の三層に関連しています場合、私はわからないよ:

grandpa: { 
    grandpa: { 
    grandpaCounter: 50 
    } 
} 

私はreselectの私の使用してngRx example-appに従うことを試みたが、おそらく私はそれらのセレクタを悪用していますか?他に何が欠けていますか?

app.component.html

<button (click)="increment()">Increment</button> 
<button (click)="decrement()">Decrement</button> 
<div>Current Count: {{ grandpaCounter$ | async }}</div> 

<button (click)="resetCounter()">Reset Counter</button> 

app.module.ts

// Native angular modules 
import { NgModule } from '@angular/core' 
import { BrowserModule } from '@angular/platform-browser' /* Registers critical application service providers */ 
import { BrowserAnimationsModule } from '@angular/platform-browser/animations' 
import { HttpClientModule } from '@angular/common/http' 

// Bootstrap component 
import { AppComponent } from './app.component' 

// ngRx 
import { StoreModule } from '@ngrx/store' 
import { StoreDevtoolsModule } from '@ngrx/store-devtools' 
import { EffectsModule } from '@ngrx/effects' 
import { 
    StoreRouterConnectingModule, 
    routerReducer as router 
} from '@ngrx/router-store' 

// Router 
import { AppRoutingModule } from './app.routing' 

// Shared module 
import { SharedModule } from './shared/shared.module' 

// Functional modules 
import { GrandpaModule } from './modules/grandpa/grandpa.module' 

// ngRx store middleware 
import { metaReducers } from './app.store' 

// Configuration 
import { APP_CONFIG, AppConfig } from './app.config' 

@NgModule({ 
    imports: [ 
    BrowserModule, 
    BrowserAnimationsModule, 
    StoreModule.forRoot({ router: router }, { metaReducers }), 
    StoreRouterConnectingModule, 
    StoreDevtoolsModule.instrument({ 
     maxAge: 25 // Retains last 25 states 
    }), 
    EffectsModule.forRoot([]), 
    HttpClientModule, 
    SharedModule, 
    GrandpaModule, 
    AppRoutingModule // must be last 
    ], 
    declarations: [AppComponent], 
    providers: [{ provide: APP_CONFIG, useValue: AppConfig }], 
    bootstrap: [AppComponent] 
}) 
export class AppModule {} 

app.store.ts

// ngRx 
import { ActionReducer, MetaReducer } from '@ngrx/store' 

import { storeLogger } from 'ngrx-store-logger' 

// Root state 
export interface State {} 

/* Meta-reducers */ 
export function logger(reducer: ActionReducer<State>): any { 
    // default, no options 
    return storeLogger()(reducer) 
} 

export const metaReducers = process.env.ENV === 'production' ? [] : [logger] 

grandpa.module.ts

// Native angular modules 
import { NgModule } from '@angular/core' 

// ngRx 
import { StoreModule } from '@ngrx/store' 

// Shared module 
import { SharedModule } from '../../shared/shared.module' 

// Functional Components 
import { GrandpaComponent } from './grandpa.component' 

// Router 
import { GrandpaRoutingModule } from './grandpa.routing' 

// Store 
import { branchReducers } from './grandpa.store' 

@NgModule({ 
    imports: [ 
    StoreModule.forFeature('grandpa', branchReducers), 
    SharedModule, 
    GrandpaRoutingModule // must be last 
    ], 
    declarations: [GrandpaComponent] 
}) 
export class GrandpaModule {} 

grandpa.store.ts

// ngRx 
import { ActionReducerMap, createSelector } from '@ngrx/store' 

// Module branch reducers 
import * as grandpaReducer from './grandpa.reducer' 

// Feature state 
export interface State { 
    grandpa: grandpaReducer.State 
} 

// Feature reducers map 
export const branchReducers: ActionReducerMap<State> = { 
    grandpa: grandpaReducer.reducer 
} 

// Module selectors 
export const getGrandpaState = (state: State) => state.grandpa 

export const getGrandpaCounter = createSelector(
    getGrandpaState, 
    grandpaReducer.getGrandpaCounter 
) 

grandpa.reducer.ts

import { createSelector } from '@ngrx/store' 

import * as GrandpaActions from './grandpa.actions' 
import * as grandpaStore from './grandpa.store' 

export interface State { 
    grandpaCounter: number 
} 

export const initialState: State = { 
    grandpaCounter: 50 
} 

export function reducer(state = initialState, action: GrandpaActions.Actions) { 
    switch (action.type) { 
    case GrandpaActions.INCREMENT: 
     return { grandpaCounter: state.grandpaCounter + 1 } 

    case GrandpaActions.DECREMENT: 
     return { grandpaCounter: state.grandpaCounter - 1 } 

    case GrandpaActions.RESET_COUNTER: 
     return { grandpaCounter: initialState.grandpaCounter } 

    default: 
     return { grandpaCounter: state.grandpaCounter } 
    } 
} 

// Selectors 
export const getGrandpaCounter = (state: State) => state.grandpaCounter 

grandpa.component.ts

import { Component } from '@angular/core' 

import { Observable } from 'rxjs/Observable' 

import { Store } from '@ngrx/store' 

import * as GrandpaActions from './grandpa.actions' 
import * as grandpaStore from './grandpa.store' 

@Component({ 
    selector: 'portal-grandpa', 
    templateUrl: './grandpa.component.html' 
}) 
export class GrandpaComponent { 
    grandpaCounter$: Observable<number> 

    constructor(private store: Store<grandpaStore.State>) { 
    this.grandpaCounter$ = store.select(grandpaStore.getGrandpaCounter) 
    } 
    increment() { 
    this.store.dispatch(new GrandpaActions.Increment()) 
    } 
    decrement() { 
    this.store.dispatch(new GrandpaActions.Decrement()) 
    } 
    resetCounter() { 
    this.store.dispatch(new GrandpaActions.ResetCounter()) 
    } 
} 
+0

ngrxのバージョンは何ですか? –

+0

@RahulSingh ngrx 4 –

答えて

0

これは状態ツリーとセレクタになりました。

import { Component } from '@angular/core' 

import { Observable } from 'rxjs/Observable' 

import { Store } from '@ngrx/store' 

import * as GrandpaActions from './grandpa.actions' 
import * as grandpaStore from './grandpa.store' 

@Component({ 
    selector: 'portal-grandpa', 
    templateUrl: './grandpa.component.html' 
}) 
export class GrandpaComponent { 
    grandpaCounter$: Observable<number> 

    constructor(private store: Store<grandpaStore.State>) { 
    this.grandpaCounter$ = store.select(grandpaStore.getS2) 
    } 
    increment() { 
    this.store.dispatch(new GrandpaActions.Increment()) 
    } 
    decrement() { 
    this.store.dispatch(new GrandpaActions.Decrement()) 
    } 
    resetCounter() { 
    this.store.dispatch(new GrandpaActions.ResetCounter()) 
    } 
} 

私はを

grandpa.store.ts

// ngRx 
import { 
    ActionReducerMap, 
    createSelector, 
    createFeatureSelector 
} from '@ngrx/store' 

// Branch reducers 
import * as grandpaReducer from './grandpa.reducer' 

// State 
export interface State { 
    grandpa: grandpaReducer.State 
} 

// Reducers map 
export const branchReducers: ActionReducerMap<State> = { 
    grandpa: grandpaReducer.reducer 
} 

// Selectors 
export const getS0 = createFeatureSelector<State>('grandpa') 
export const getS1 = (state: State) => state.grandpa 
export const getS01 = createSelector(getS0, getS1) 
export const getS2 = createSelector(getS01, grandpaReducer.getGrandpaCounter) 

grandpa.component.ts:私は国家の三つのレベルに私のセレクタスライスを定義するために必要なぜレデューサー状態とそのダイレクトセレクターを取り付けるのがうまくいかないのかまだ分かりません。

grandpa.reducer.ts

export const getGrandpaCounter = (state: State) => state.grandpaCounter

grandpa.componentを:私は、この単一のセレクタはそれで働いているだろうと思っているだろう。ts

import { Component } from '@angular/core' 

import { Observable } from 'rxjs/Observable' 

import { Store } from '@ngrx/store' 

import * as GrandpaActions from './grandpa.actions' 

import * as grandpaReducer from './grandpa.reducer' 

@Component({ 
    selector: 'portal-grandpa', 
    templateUrl: './grandpa.component.html' 
}) 
export class GrandpaComponent { 
    grandpaCounter$: Observable<number> 

    constructor(private store: Store<grandpaReducer.State>) { 
    this.grandpaCounter$ = store.select(grandpaReducer.getGrandpaCounter) 
    } 
    increment() { 
    this.store.dispatch(new GrandpaActions.Increment()) 
    } 
    decrement() { 
    this.store.dispatch(new GrandpaActions.Decrement()) 
    } 
    resetCounter() { 
    this.store.dispatch(new GrandpaActions.ResetCounter()) 
    } 
} 
関連する問題