ngrx/store影响嵌套对象

Lop*_*eur 3 ngrx ngrx-effects angular ngrx-store

我正在学习Angular 2,我正在尝试使用ngrx/store,但是我遇到了一些特殊情况的困难.

示例我正在尝试删除父对象.我想要做的是删除子对象.

这是我的实体:

export class Discussion {
  id: string;
  name: string;
  createdAt: Date;
  posts: Post[];
}

export class Post {
  id: string;
  title: string;
  data: string;
  createdAt: Date;
  comments: Comment[];
}

export class Comment {
  id: string;
  data: string;
  createdAt: Date;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用normalizr来平整我的状态,所以我存储的讨论将如下所示:

{
  id: "1",
  name: "First dicussion",
  createdAt: "...",
  posts: ["1", "2", "3", "5"]
}
Run Code Online (Sandbox Code Playgroud)

我有3个减速器,一个用于讨论的减速器,另一个用于帖子,最后一个用于评论.所有reducers都会处理删除自己类型的Action.以下是Discussion reducer的示例:

export function reducer(state = initialState, action: discussion.Actions): State {
switch (action.type) {
    case discussion.REMOVE: {
        const idToRemove = action.payload;
        const newEntities = state.entities;
        delete newEntities[idToRemove];
        return Object.assign({}, state, {
            entities: newEntities
        });
    }
}}
Run Code Online (Sandbox Code Playgroud)

我的动作如下:

export class RemoveAction implements Action {
readonly type = REMOVE;

/**
 * Constructor
 * @param payload The id of the discussion to remove
 */
constructor(public payload: string) { }
}
Run Code Online (Sandbox Code Playgroud)

当我删除讨论时,我想删除与讨论相关的帖子,帖子效果将删除与删除的帖子相关的评论.我使用了ngrx的效果,所以我使用了这个效果:

@Effect()
removeDiscussion: Observable<Action> = this._actions
.ofType(dicussion.REMOVE)
.map((action: discussion.RemoveAction) => action.payload)
.mergeMap(discId => {

    // How to get posts from discussion id ???

    // Fire related Actions
    return [
        new posts.RemoveAction(postsToRemove)
    ];
});
Run Code Online (Sandbox Code Playgroud)

我的问题是如何从讨论ID中删除帖子?

谢谢阅读.

mtx*_*mtx 6

您可以使用在效果中访问商店withLatestFrom.
(import 'rxjs/add/operator/withLatestFrom';)

在效果类中注入商店:

constructor(private _actions: Actions, private store: Store<fromRoot.State>)
Run Code Online (Sandbox Code Playgroud)

在效果中使用它:

@Effect()
removeDiscussion: Observable<Action> = this._actions
    .ofType(dicussion.REMOVE)
    .map((action: discussion.RemoveAction) => action.payload)
    .withLatestFrom(this.store, (payload, state) => ({ discId: payload, state }))
    .mergeMap(({ discId, state }) => {
        // access the posts array of the discussion
        const postsToRemove = state.discussions[discId].posts;

        // Fire related Actions
        return [
            new posts.RemoveAction(postsToRemove)
        ];
    });
Run Code Online (Sandbox Code Playgroud)

语法.mergeMap(({ discId, state }) => ...称为解构.
如果您不喜欢这种语法,可以将其替换为.mergeMap((payloadAndState) => ....那你就可以discId通过做了payloadAndState.discId