mister.component
calls store.dispatch(quack)
export class MisterComponent implements OnInit {
constructor(private store: Store<fromRoot.State>) { }
onClick() {
this.store.dispatch({ type: actionTypes.QUACK });
}
}
mister.reducer
updates the state
export const reducer = handleActions<State>(
{
[actionTypes.QUACK]: state => {
return Object.assign({}, state, { says: 'Quack!' });
},
},
initialState);
mister.component
renders new state
export class MisterComponent implements OnInit {
says$: Observable<string>;
constructor(private store: Store<fromRoot.State>) { }
ngOnInit() {
this.says$ = this.store.select(s => s.mister.says);
}
}
<figure>
<img src="assets/mister.png">
<figcaption>
<h2>{{says$ | async}}</h2>
</figcaption>
</figure>
missus.reducer
responds to mister's QUACK action
export const reducer = handleActions<State>(
{
[misterActionTypes.QUACK]: state => {
return Object.assign({}, state, { says: 'Quack!' });
},
},
initialState);
duckling.effects connects actions together
@Effect()
misterQuack$: Observable<Action> = this.actions$
.ofType(misterActionTypes.QUACK)
.map(() => ducklingQuackAction(0));
@Effect()
ducklingQuack$: Observable<Action> = this.actions$
.ofType(actionTypes.QUACK).map(toPayload)
.withLatestFrom(
this.store.select(fromRoot.getDucklingState)
)
.filter(([ducklingIndex, ducklings])
=> ducklingIndex < ducklings.length - 1)
.map(([ducklingIndex])
=> ducklingQuackAction(ducklingIndex + 1))
.delay(400);
missus.effects is overwhelmed
@Effect()
missusSquawk$: Observable<Action> = this.actions$
.ofType(misterActionTypes.QUACK)
.delay(4000)
.map(() => squawkAction());
Small changes for big wins
const reducers = {
duckling: fromDuckling.reducer,
missus: fromMissus.reducer,
mister: fromMister.reducer,
};
const reducer
= compose(undoable, combineReducers)(reducers);
@NgModule({
imports: [StoreModule.provideStore(reducer)],
})
export class AppModule { }