@ ngrx / store:从动作中分派。好吗&怎么样?

时间:2016-07-07 12:09:28

标签: angular typescript redux ngrx

我正在研究一个使用Angular 2和@ ngrx / store.question的项目,了解一个好的做法以及如何做到这一点。

我开发了一个“网页查找器”来管理文件。所以我可以做一些基本的动作,如复制,移动等。

我不解释原因,因为它只是一个示例,但移动文件包含3个步骤:

  • 逻辑:做一些验证。
  • 发出行动A
  • 发送行动B

这三个步骤是在我的角度组件内完成的。我已经考虑过了,我认为简单地发送一个动作进行一些验证并发送其他两个动作是个更好的主意。

我为什么要这样做?首先,它更容易阅读

this._store.dispatch(copy(myFile));

而不是

// ...
// verifications
// ...

this._store.dispatch(action1(myFile, foo, bar));
this._store.dispatch(action2(myFile));

其次,我可以动态派遣我的copy动作创建者而不会遇到任何副作用,因为验证将在动作中执行。

实际上,我可以在不进行验证的情况下发送action1 et action2

最后,我的所有逻辑都在我的行动中。我可以保持我的组件简单并专注于他们的工作(管理UI等)。哪个好。

问题1:良好做法?

我认为这样做是个好主意吗?我想是这样,但你的经历让我感兴趣。

问题2:如何?

怎么做?我的动作创作者只是功能。我无法使用Injectable修饰它们并使用constructor来注入实例。

以下是动作创建者的示例:

import { Action } from '@ngrx/store'

export const NAVIGATE_TO_NODE:string = '[Browser] Navigate to node';
export const ADD_TO_SELECTION:string = '[Browser] Add to browser selection';
export const REMOVE_FROM_SELECTION:string = '[Browser] Remove from browser selection';
export const REMOVE_ALL_FROM_SELECTION:string = '[Browser] Remove all from browser selection';

export const navigateToNode:(nodeId: number, paneId?: number)=>Action = (nodeId: number, paneId?: number) => {
  return {
    payload: { nodeId, paneId },
    type: NAVIGATE_TO_NODE
  };
};
export const addToSelection: (addInfo: any)=>Action = (addInfo: any) => {
  return {
    payload: addInfo,
    type: ADD_TO_SELECTION
  };
};
export const removeFromSelection: (removeInfo: any[])=>Action = (removeInfo: any[]) => {
  return {
    payload: removeInfo,
    type: REMOVE_FROM_SELECTION
  }
};
export const removeAllFromSelection: ()=>Action = () => {
  return {
    payload: null,
    type: REMOVE_ALL_FROM_SELECTION
  }
};

如何从这些动作创作者发送?

我已经使用redux作为Reux的Redux实现,并且我已经创建了一个允许我从动作创建者发送的小包:redux-thunk

2 个答案:

答案 0 :(得分:2)

我将第二个有线程序员的建议来查看ngrx示例应用程序。它展示了如何构建动作,缩减器和效果。

以下是可注射动作类的示例。

@Injectable()
export class BookActions {
  static SEARCH = '[Book] Search';
  search(query: string): Action {
    return {
      type: BookActions.SEARCH,
      payload: query
    };
  }

然后在你的组件中......

constructor(private store: Store<AppState>, private bookActions: BookActions) {}

search(query: SearchOutput) {
  this.store.dispatch(this.bookActions.search(query));
}

这样接近它。减速器应该是纯函数,没有副作用。因此,例如,要移动文件,您可以调度启动事务的操作,该操作可以设置具有文件名,目标名称以及所需的任何其他操作详细信息的状态。该函数将返回新状态。将此缩减器称为START_MOVE。

在您的效果中,请注意START_MOVE,获取包含交易详情的状态,然后执行交易的第一部分。完成后,将具有更新状态的操作分派给MOVE_2,或更具描述性的内容。

此缩减器设置状态,包含下一步所需的详细信息,并将其返回。

效果观察MOVE_2,然后进行交易的第二阶段。完成后,发送MOVE_3。作为一个函数,它只是为第三部分设置状态,效果获取细节并完成事务。完成后,调度MOVE_SUCCESS,使用新文件名或其他任何方式设置状态。

如果发生错误,过程中的任何一点都可以调度MOVE_ERROR,并以类似的方式处理清理或返回初始状态。或者如果需要,可以MOVE_CANCEL。

组件可以观察状态并将状态更新给用户。

答案 1 :(得分:1)

很抱歉要简短,但我只是略过了你的问题而这只是对其中一部分的回应。如果你想让你的动作创建者可注射,那么将它们包装在一个类中。您可以从ngrx示例应用程序中获得关于ngrx / store自述文件的结构的一些优秀创意。 我正在创建一个项目,我已经模仿了他们的动作创建者设置。

https://github.com/ngrx/example-app/tree/master/src/actions