2017-09-02 2 views
0

Ich verwende eine ziemlich konstruierte Reihe von Beispielen aus der ngRx docs, um zu versuchen und mit einem Redux-Modell für unsere Angular App zu beginnen. Der folgende Code funktioniert - alle Aktionen werden ausgelöst und der Store wird korrekt aktualisiert. Ich kann sie in den Redux-Dev-Tools und im Store-Logger sehen.ngRx/store Observable Wert nicht in Angular Vorlage angezeigt

Ich kann jedoch nichts in der Vorlage angezeigt werden. Es ist nur leer. Ich bin nicht sicher, ob es um die drei Schichten des Zustandsbaumes in engen Zusammenhang steht, das wie folgt aussieht:

grandpa: { 
    grandpa: { 
    grandpaCounter: 50 
    } 
} 

ich versucht habe, die NGRX example-app mit meiner Verwendung von reselect, zu folgen, aber vielleicht jene Wähler ich mißbrauchen? Was könnte ich noch vermissen?

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

was ist die Version von ngrx? –

+0

@RahulSingh ngrx 4 –

Antwort

0

Es endete damit, dass der Statusbaum und die Selektoren. Ich musste meine Wähler Scheiben aus den drei Ebenen von Staat definieren:

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

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

Ich bin immer noch nicht sicher, warum die Befestigung des Reduzierers und dessen direkter Wahlschalter nicht funktioniert.

grandpa.reducer.ts

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

grandpa.component: Ich würde diese einzelnen Wähler mit ihm hätten gearbeitet haben gedacht.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()) 
    } 
}