• 通过Dispatching Actions 修改应用的 State
    • 同步Actions
    • 异步 Actions
    • 依赖其它服务的 Actions

    通过Dispatching Actions 修改应用的 State

    大多数Redux应用程序都有一组功能,称为“action creators”,用于设置和dispatch action。

    在Angular中,将您的操作创建者定义为@Injectable()服务非常方便,将dispatch,创建和副作用逻辑与应用程序中的@Component类分离。

    同步Actions

    app/store/counter/counter.actions.ts

    1. import {Injectable} from '@angular/core';
    2. import {Store} from '@ngrx/store';
    3. import {createAction} from '../createAction';
    4. import {AppState} from '../../models/appState';
    5. @Injectable()
    6. export class CounterActions {
    7. static INCREMENT = 'INCREMENT';
    8. static DECREMENT = 'DECREMENT';
    9. static RESET = 'RESET';
    10. constructor(private store: Store<AppState>) {
    11. }
    12. increment() {
    13. this.store.dispatch(createAction(CounterActions.INCREMENT));
    14. }
    15. decrement() {
    16. this.store.dispatch(createAction(CounterActions.DECREMENT));
    17. }
    18. reset() {
    19. this.store.dispatch(createAction(CounterActions.RESET));
    20. }
    21. }

    如你所见,动作创建者是简单的函数,它dispatch包含更多描述状态修改信息的Action对象。

    异步 Actions

    如果必须处理异步或条件actions(react-redux 用户可能将这种模式识别为依赖注入世界中的redux-thunk),则“ActionCreatorService”模式非常方便。

    app/store/counter/counter.actions.ts

    1. import {Injectable} from '@angular/core';
    2. import {Store} from '@ngrx/store';
    3. import {createAction} from '../createAction';
    4. import {AppState} from '../../models/appState';
    5. @Injectable()
    6. export class CounterActions {
    7. constructor(private store: Store<AppState>) {
    8. }
    9. incrementIfOdd() {
    10. this.store.select(appState => appState.counter.currentValue)
    11. .take(1)
    12. .subscribe(currentValue => {
    13. if (currentValue % 2 !== 0) {
    14. this.store.dispatch(createAction(CounterActions.INCREMENT);
    15. }
    16. });
    17. }
    18. incrementAsync(timeInMs: number = 1000) {
    19. this.delay(timeInMs).then(() => this.store.dispatch(createAction(CounterActions.INCREMENT)));
    20. }
    21. private delay(timeInMs: number) {
    22. return new Promise((resolve) => {
    23. setTimeout(() => resolve() , timeInMs);
    24. });
    25. }
    26. }

    incrementIfOdd()动作创建者中,我们在应用程序 state 中创建一个计时器的currentValue的一次性订阅。在那里,我们在dispatching action之前是检查是否为奇数。

    incrementAsync()动作创建者中,我们延迟对dispatch()的实际调用。我们创造了一个在延迟后解析的Promise。一旦Promise解析了,我们可以dispatch一个action来增加计数器。

    依赖其它服务的 Actions

    在你的操作创建者必须使用其他角色服务的情况下,ActionCreatorService模式才是必需的。考虑下面的SessionActions服务来处理远程API调用:

    1. import {Injectable} from '@angular/core';
    2. import {Store} from '@ngrx/store';
    3. import {createAction} from '../createAction';
    4. import {AppState} from '../../models/appState';
    5. @Injectable()
    6. export class SessionActions {
    7. static LOGIN_USER_PENDING = 'LOGIN_USER_PENDING';
    8. static LOGIN_USER_SUCCESS = 'LOGIN_USER_SUCCESS';
    9. static LOGIN_USER_ERROR = 'LOGIN_USER_ERROR';
    10. static LOGOUT_USER = 'LOGOUT_USER';
    11. constructor(
    12. private store: Store<AppState>,
    13. private authService: AuthService
    14. ) {
    15. }
    16. loginUser(credentials: any) {
    17. this.store.dispatch(createAction(SessionActions.LOGIN_USER_PENDING));
    18. this.authService.login(credentials.username, credentials.password)
    19. .then(result => this.store.dispatch(createAction(SessionActions.LOGIN_USER_SUCCESS, result)))
    20. .catch(() => this.store.dispatch(createAction(SessionActions.LOGIN_USER_ERROR)));
    21. };
    22. logoutUser() {
    23. this.store.dispatch(createAction(SessionActions.LOGOUT_USER));
    24. };
    25. }