ngrx/store的效果嵌套对象

4

我正在学习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;
}

我正在使用normalizr来扁平化我的状态,以便我的存储讨论看起来像这样:
{
  id: "1",
  name: "First dicussion",
  createdAt: "...",
  posts: ["1", "2", "3", "5"]
}

我有三个reducers,一个用于讨论(Discussions),另一个用于帖子(Posts),最后一个用于评论(Comments)。所有的reducers都处理它们自己类型的删除操作。以下是讨论(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
        });
    }
}}

我的行动看起来像这样:

export class RemoveAction implements Action {
readonly type = REMOVE;

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

当我删除一次讨论时,我希望删除与该讨论相关的帖子,并且影响将删除与已删除帖子相关的评论。为了做到这一点,我使用了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)
    ];
});

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

谢谢阅读。

1个回答

7
您可以使用withLatestFrom来访问存储区。
(import 'rxjs/add/operator/withLatestFrom';)

在effects类中注入store:

constructor(private _actions: Actions, private store: Store<fromRoot.State>)

在使用效果中应用:

@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)
        ];
    });

.mergeMap(({ discId, state }) => ...语法被称为解构赋值
如果您不喜欢这种语法,可以用.mergeMap((payloadAndState) => ...替换。然后通过payloadAndState.discId 访问 discId


你好mtx, 谢谢你的回答。这正是我在寻找的。 我不知道withLatestFrom,所以我想知道如何访问状态对象。 此外,解构语法非常酷,谢谢你也提到了它。 对于在使用withLatestFrom时遇到错误的人,请不要忘记添加import'rxjs/add/operator/withLatestFrom';。由于我是初学者,我忘记了添加它。 - Lopeur
很高兴能够帮到您。我在答案中添加了导入语句,以防其他人遇到这个问题。感谢提示! - mtx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接